0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

互斥鎖不能在中斷中使用?

冬至子 ? 來源:ITRelief ? 作者:Sachefgh Xu ? 2023-07-25 15:36 ? 次閱讀

互斥鎖的概念

互斥鎖是一種特殊的二值信號(hào)量,因?yàn)樗鉀Q了優(yōu)先級(jí)翻轉(zhuǎn)的問題??梢酝ㄟ^優(yōu)先級(jí)繼承機(jī)制來解決:當(dāng)另外一個(gè)的任務(wù)試圖獲取同一個(gè)互斥鎖時(shí),已經(jīng)獲得互斥鎖的任務(wù)將繼承該任務(wù)的優(yōu)先級(jí)。

互斥鎖有一個(gè)比較明顯的特點(diǎn),即它必須哪一個(gè)線程申請(qǐng),就由該線程來釋放。而在二值信號(hào)量中,釋放和獲取token的線程可以不一致。因此,在處理線程之間占用同一硬件資源的問題時(shí)首先考慮使用互斥鎖。

API Description 【互斥鎖不能在中斷中使用】

①創(chuàng)建互斥鎖

在CMSIS-RTOS中,互斥鎖通過 ***osMutexNew() *** 函數(shù)和配置結(jié)構(gòu)體 *osMutexAttr_t *建立。

1)配置結(jié)構(gòu)體osMutexAttr_t

osMutexAttr_t 中功能參數(shù) *attr_bits ***用于配置互斥鎖的功能特性,相當(dāng)重要;參數(shù)相關(guān)定義包括: **

1.* osMutexRecursive * - 創(chuàng)建遞歸互斥鎖。當(dāng)上鎖開鎖的程序段遞歸時(shí),會(huì)出現(xiàn)多重加鎖的情況,并從深處向外解鎖。此時(shí)應(yīng)當(dāng)引入對(duì)遞歸的支持。本參數(shù)配置了一個(gè)遞歸計(jì)數(shù)機(jī)制,允許同一個(gè)線程多重加鎖;調(diào)用一次計(jì)數(shù)+1,釋放-1;當(dāng)計(jì)數(shù)回到0時(shí)此鎖解開。

2.osMutexPrioInherit - 優(yōu)先級(jí)繼承機(jī)制。可以防止優(yōu)先級(jí)翻轉(zhuǎn)。

  1. *osMutexRobust * - 互斥鎖回收機(jī)制。當(dāng)加鎖的線程被 osThreadExit() 或 *osThreadTerminate() *終止而未能解鎖時(shí),鎖將會(huì)自動(dòng)回收。

上述三個(gè)參數(shù)可以通過邏輯或( | )組合傳入結(jié)構(gòu)體。

typedef struct {
  const char                   *name;   ///名稱,僅標(biāo)識(shí)用
  uint32_t                 attr_bits;   ///功能參數(shù);重要
  void                       *cb_mem;   /// memory for control block;Default ==NULL
  uint32_t                   cb_size;   /// Default==0U
} osMutexAttr_t;

@param    attr_bits:  -參數(shù)配置;可通過邏輯或 輸入復(fù)數(shù)的參數(shù)
        / osMutexPrioInherit  -使用優(yōu)先級(jí)繼承
        / osMutexRecursive    -遞歸互斥鎖
        / osMutexRobust       -自回收;當(dāng)線程終止時(shí)自動(dòng)釋放持有的token
  1. 通過 ***osMutexNew() ***創(chuàng)建目標(biāo)互斥鎖
osMutexId_t osMutexNew (const osMutexAttr_t *attr);/*創(chuàng)建互斥鎖
@param    *attr    -osMutexAttr_t互斥鎖配置結(jié)構(gòu)體
@retval    -句柄(地址)
            ==NULL   創(chuàng)建失敗*/

**②刪除互斥鎖 **osMutexDelete()

osStatus_t osMutexDelete( osMutexId_t  mutex_id );/*刪除互斥鎖
@retval:    -osOK //成功
            -osErrorParameter: parameter mutex_id is NULL or invalid.
            -osErrorResource: the mutex is in an invalid state.(其他錯(cuò)誤)
            -osErrorISR: 在中斷調(diào)用導(dǎo)致的錯(cuò)誤
*/

③獲取互斥鎖token osMutexAcquire()

互斥鎖token的獲取與二值信號(hào)量基本一致。 線程調(diào)用該函數(shù)時(shí),當(dāng)鎖中無token時(shí),線程進(jìn)入BLOCK狀態(tài)等待消息量被放入token;。在此期間當(dāng)任務(wù)檢測(cè)到消息量放入token時(shí),將自動(dòng)由****BLOCK態(tài)轉(zhuǎn)移為READY態(tài)。當(dāng)?shù)却臅r(shí)間超過了指定的阻塞時(shí)間,即使隊(duì)列中尚無數(shù)據(jù),任務(wù)也會(huì)自動(dòng)從阻塞態(tài)轉(zhuǎn)移為READY態(tài)。此時(shí)程序會(huì)返回osErrorTimeout錯(cuò)誤。若沒有設(shè)置阻塞超時(shí)且參數(shù)正確,返回osErrorResource錯(cuò)誤**。**

osStatus_t osMutexAcquire (osMutexId_t mutex_id, uint32_t timeout);/*取得token;
@param      timeout      阻塞等待時(shí)間
@retval    -osOK: the mutex has been obtained.
           -osErrorTimeout: the mutex could not be obtained in the given time.
           -osErrorResource: the mutex could not be obtained when no timeout was specified.
           -osErrorParameter: parameter mutex_id is NULL or invalid.
           -osErrorISR: cannot be called from interrupt service routines.
*/

timeout參數(shù):

== 0U //不設(shè)置阻塞超時(shí)時(shí)間,若出現(xiàn)異常函數(shù)將直接報(bào)錯(cuò)返回
== osWaitForever //任務(wù)將一直阻塞直到鎖中token被相應(yīng)線程歸還
== Ticks //設(shè)置具體等待時(shí)間,單位為RTOS心跳數(shù)(Ticks)

④歸還互斥鎖tokenosMutexRelease() ****

注意互斥鎖的token歸還只能由獲取的線程進(jìn)行,否則系統(tǒng)會(huì)報(bào)Resource錯(cuò)誤。

osStatus_t osMutexRelease (osMutexId_t mutex_id);/*歸還互斥鎖
@retval      -osOK: 成功
             -osErrorResource: 無法歸還(當(dāng)前token沒有被獲取 或 本線程不持有互斥鎖的token)
             -osErrorParameter: parameter mutex_id is NULL or invalid.
             -osErrorISR: 在中斷中調(diào)用了本函數(shù)
*/
```**⑤查詢當(dāng)前互斥鎖token的擁有者(線程)****  ***osMutexGetOwner()*********

osThreadId_t osMutexGetOwner (osMutexId_t mutex_id)/*
@retval -持有互斥鎖token的線程句柄(ID);
若token未被持有或 發(fā)生錯(cuò)誤,則返回NULL
*/


聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 處理器
    +關(guān)注

    關(guān)注

    68

    文章

    19048

    瀏覽量

    228530
  • RTOS
    +關(guān)注

    關(guān)注

    21

    文章

    808

    瀏覽量

    119303
  • ISR
    ISR
    +關(guān)注

    關(guān)注

    0

    文章

    38

    瀏覽量

    14381
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    Linux高級(jí)編程---互斥

    在Linux系統(tǒng)里,有很多的應(yīng)用,包括互斥,文件,讀寫等等,信號(hào)量其實(shí)也應(yīng)該是的一種。
    發(fā)表于 01-13 10:07

    信號(hào)量、互斥、自旋

    信號(hào)量、互斥、自旋http://bbs.edu118.com/forum.php?mod=viewthread&tid=488&fromuid=231(出處: 信盈達(dá)IT技術(shù)社
    發(fā)表于 08-29 09:48

    BearPi-HM_Nano開發(fā)板鴻蒙OS內(nèi)核編程開發(fā)——互斥

    :不能在中斷服務(wù)調(diào)用該函數(shù)參數(shù):[td]名字描述attr互斥對(duì)象的屬性.osMutexAcquire()osStatus_t osMutexAcquire(osMutexId_t mutex_id
    發(fā)表于 04-09 10:02

    如何在RK2206上使用鴻蒙LiteOS-M內(nèi)核接口進(jìn)行互斥編程開發(fā)

    注意的是,互斥不能在中斷服務(wù)程序中使用。API分析LOS_MuxCreate()UINT32 LOS_MuxCreate(UINT32 *
    發(fā)表于 08-05 16:28

    很多變量多線程讀寫是使用關(guān)中斷好還是使用互斥進(jìn)行保護(hù)呢?

    會(huì)打斷當(dāng)前線程去獲取同一個(gè)互斥量,由于被占,高優(yōu)先級(jí)掛起,低優(yōu)先級(jí)繼續(xù)執(zhí)行,釋放互斥后高優(yōu)先級(jí)執(zhí)行。這樣會(huì)有多兩次線程切換開銷。 2.如果在讀寫的時(shí)候進(jìn)入
    發(fā)表于 05-05 14:14

    華為物聯(lián)網(wǎng)操作系統(tǒng)LiteOS內(nèi)核教程05-互斥

    1. LiteOS的互斥 1.1. 互斥 在多任務(wù)環(huán)境下,往往存在多個(gè)任務(wù)競(jìng)爭(zhēng)同一共享資源的應(yīng)用場(chǎng)景,互斥
    發(fā)表于 03-13 16:19 ?1130次閱讀
    華為物聯(lián)網(wǎng)操作系統(tǒng)LiteOS內(nèi)核教程05-<b class='flag-5'>互斥</b><b class='flag-5'>鎖</b>

    深入了解互斥、條件變量、讀寫以及自旋

    C++11只包含其中的部分。接下來我主要通過pthread的API來展開本文。 mutex(互斥量) mutex(mutual exclusive)即互斥量(互斥體)。也便是常說的互斥
    的頭像 發(fā)表于 11-01 10:02 ?1843次閱讀

    Linux中的傷害/等待互斥介紹

    序言:近期讀Linux 5.15的發(fā)布說明,該版本合并了實(shí)時(shí)機(jī)制,當(dāng)開啟配置宏CONFIG_PREEMPT_RT的時(shí)候,這些被基于實(shí)時(shí)互斥的變體替代:mutex、ww_mutex
    的頭像 發(fā)表于 11-06 17:27 ?2590次閱讀

    Linux下線程間通訊--互斥

    互斥是一種簡單的加鎖的方法來控制對(duì)共享資源的存取,當(dāng)多個(gè)線程訪問公共資源時(shí),為了保證同一時(shí)刻只有一個(gè)線程獨(dú)占資源,就可以通過互斥加以限制,在一個(gè)時(shí)刻只能有一個(gè)線程掌握某個(gè)
    的頭像 發(fā)表于 08-24 15:53 ?1907次閱讀
    Linux下線程間通訊--<b class='flag-5'>互斥</b><b class='flag-5'>鎖</b>

    Linux互斥的作用 互斥是什么

    。如果釋放互斥時(shí)有一個(gè)以上的線程阻塞,那么這些阻塞的線程會(huì)被喚醒,它們都會(huì)嘗試對(duì)互斥進(jìn)行加鎖,當(dāng)有一個(gè)線程成功對(duì)互斥鎖上鎖之后,其它線程
    的頭像 發(fā)表于 07-21 11:13 ?861次閱讀

    自旋互斥的區(qū)別有哪些

    自旋 自旋互斥很相似,在訪問共享資源之前對(duì)自旋進(jìn)行上鎖,在訪問完成后釋放自旋(解鎖)
    的頭像 發(fā)表于 07-21 11:19 ?9253次閱讀

    互斥、條件變量、讀寫、自旋及信號(hào)量介紹

    一、互斥(同步) 在多任務(wù)操作系統(tǒng)中,同時(shí)運(yùn)行的多個(gè)任務(wù)可能都需要使用同一種資源。這個(gè)過程有點(diǎn)類似于,公司部門里,我在使用著打印機(jī)打印東西的同時(shí)(還沒有打印完),別人剛好也在此刻使用打印機(jī)打印東西
    的頭像 發(fā)表于 11-10 16:16 ?1492次閱讀
    <b class='flag-5'>互斥</b><b class='flag-5'>鎖</b>、條件變量、讀寫<b class='flag-5'>鎖</b>、自旋<b class='flag-5'>鎖</b>及信號(hào)量介紹

    互斥和自旋的區(qū)別 自旋臨界區(qū)可以被中斷嗎?

    互斥和自旋的區(qū)別 自旋臨界區(qū)可以被中斷嗎? 互斥
    的頭像 發(fā)表于 11-22 17:41 ?721次閱讀

    自旋互斥的使用場(chǎng)景是什么

    自旋互斥是兩種常見的同步機(jī)制,它們?cè)诙嗑€程編程中被廣泛使用。在本文中,我們將介紹自旋互斥
    的頭像 發(fā)表于 07-10 10:05 ?743次閱讀

    互斥和自旋的實(shí)現(xiàn)原理

    互斥和自旋是操作系統(tǒng)中常用的同步機(jī)制,用于控制對(duì)共享資源的訪問,以避免多個(gè)線程或進(jìn)程同時(shí)訪問同一資源,從而引發(fā)數(shù)據(jù)不一致或競(jìng)爭(zhēng)條件等問題。 互斥
    的頭像 發(fā)表于 07-10 10:07 ?351次閱讀