RTX筆記7 - 互斥信號量Mutex


  互斥鎖(Mutex)可用於同步資源訪問。

  互斥(通常稱為Mutex)用於各種操作系統的資源管理。微控制器設備中的許多資源可以被重復使用,但一次只能被一個線程使用(例如通信通道、內存和文件)。互斥鎖用於保護對共享資源的訪問。創建一個互斥鎖,然后在線程之間傳遞(它們可以獲取和釋放互斥鎖)。

 

 

   互斥鎖是信號量的特殊版本。像信號量一樣,互斥鎖也是一個令牌容器,但是有一個令牌,代表一個資源。因此,互斥鎖令牌是二值的且有邊界的。

  互斥鎖的優點是它引入了線程所有權。當一個線程獲得一個互斥鎖並成為它的所有者時,后續從該線程獲取互斥鎖時將立即成功,沒有任何延遲(如果指定了osMutexRecursive屬性)。因此,互斥鎖的獲取/釋放可以嵌套。

 

 

   Note:互斥鎖相關函數不能被中斷程序調用。

  互斥鎖屬性:

osMutexAttr_t Data Fields
const char * name name of the mutex

Pointer to a constant string with a human readable name (displayed during debugging) of the mutex object.

Default: NULL no name specified.

uint32_t attr_bits attribute bits

The following bit masks can be used to set options:

  • osMutexRecursive : a thread can consume the mutex multiple times without locking itself.
  • osMutexPrioInherit : the owner thread inherits the priority of a (higher priority) waiting thread.
  • osMutexRobust : the mutex is automatically released when owner thread is terminated.

Use logical 'OR' operation to select multiple options, for example:

Default: 0 which specifies:

  • non recursive mutex: a thread cannot consume the mutex multiple times.
  • non priority raising: the priority of an owning thread is not changed.
  • mutex is not automatically release: the mutex object must be always is automatically released when owner thread is terminated.
void * cb_mem memory for control block

Pointer to a memory for the mutex control block object. Refer to Static Object Memory for more information.

Default: NULL to use Automatic Dynamic Allocation for the mutex control block.

uint32_t cb_size size of provided memory for control block

The size (in bytes) of memory block passed with cb_mem. For RTX, the minimum value is defined with osRtxMutexCbSize (higher values are permitted).

Default: 0 as the default is no memory provided with cb_mem.

  osMutexRecursive:互斥鎖嵌套屬性,同一個線程可以在不鎖定自身的情況下多次使用互斥鎖。每當擁有互斥鎖的線程獲得互斥鎖時,鎖計數就會增加。互斥鎖也必須被釋放多次,直到鎖定計數為零。當互斥量達到0時,互斥量實際上會被釋放,其他線程可以獲取互斥量。

  osMutexPrioInherit:優先級繼承屬性,使用優先級繼承屬性的互斥鎖將 ”等待線程“ 的優先級轉移給當前互斥鎖的所有者(如果所有者的線程優先級較低)。這確保了低優先級線程不會阻塞高優先級線程。否則,低優先級線程可能持有互斥鎖,但由於另一個中優先級線程而沒有獲得執行時間。如果沒有優先級繼承,等待互斥鎖的高優先級線程將被中優先級線程阻塞,稱為優先級反轉

  osMutexRobust:互斥鎖健壯屬性,如果擁有的線程被終止(通過osThreadExit或osThreadTerminate),健壯的互斥鎖將被自動釋放。非健壯互斥鎖不會被釋放,用戶必須手動確保釋放互斥鎖。

 

  osMutexId_t osMutexNew (const osMutexAttr_t *attr):

    創建一個互斥鎖,attr是互斥鎖的屬性,返回執行互斥鎖ID或者NULL。

  osStatus_t osMutexAcquire (osMutexId_t mutex_id, uint32_t timeout):

    申請互斥鎖。timeout是等待互斥鎖的節拍數,0代表立即返回,不阻塞;osWaitForever代表一直等待,直到互斥鎖可用。

    返回值:

      osOK:獲取互斥鎖成功。

      osErrorTimeout:等待超時失敗。

      osErrorResource當沒有指定超時時間時,獲得互斥鎖失敗。

      osErrorParametermutex_id參數錯誤。

      osErrorISR中斷調用錯誤。

  osStatus_t osMutexRelease (osMutexId_t mutex_id):

    釋放互斥鎖。

    返回值:

      osOK:釋放互斥鎖成功。

      osErrorResource互斥鎖不能被釋放。當前進程沒有獲取互斥鎖或者不是互斥鎖的擁有者。

      osErrorParametermutex_id參數錯誤。

      osErrorISR中斷調用錯誤。

 1 osMutexId_t mutex;
 2 const osMutexAttr_t mutex_attr = {
 3     .name = "_ledThread mutex",
 4     .attr_bits = osMutexRecursive | osMutexPrioInherit,
 5     .cb_mem = NULL,
 6     .cb_size = 0,
 7 };
 8 
 9 static void _ledThread(void *argument);
10 
11 void
12 test_mutex(void)
13 {
14     osThreadId_t thread;
15     
16     mutex = osMutexNew(&mutex_attr);
17     
18     osThreadNew(_ledThread, (void *)1, NULL);
19     osThreadNew(_ledThread, (void *)2, NULL);
20 }
21 
22 static void
23 _ledThread(void *argument)
24 {
25     osStatus_t status;
26     uint32_t id = (uint32_t)argument;
27     uint32_t delay;
28     
29     if(1 == id) {
30         delay = 500;
31     } else {
32         delay = 1000;
33     }
34         
35     for(;;) {
36         status = osMutexAcquire(mutex, osWaitForever);
37         if(osOK == status) {
38             menuShow(&seg_led, delay, 0);
39             osDelay(delay);
40             osMutexRelease(mutex);
41         }
42     }
43 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM