任务间同步 | 信号量、互斥量和事件集
本文分享自中移OneOS公眾號《任務間同步》。
多個任務操作同一塊代碼區域,這塊代碼就稱為臨界區,如果任何時刻最多只允許一個任務去使用臨界區,那么多個任務就需要互斥的訪問。當一個任務占用此資源時,其它需要該資源的任務必須等待,直到占用者釋放資源。
另外一種使用場景是任務間同步,是指多個關聯任務需要按預定的次序運行,如果沒有同步,那任務之間將是無序、不符合預期的。
互斥量
互斥量有解鎖和加鎖兩種狀態,初始化時互斥量處于解鎖狀態,當有任務獲取該互斥量后,處于加鎖狀態,此時其他任務沒有權限再獲取該互斥量,直到當前任務釋放。同時,互斥量具有遞歸特性,持有該互斥量的任務也能夠再次獲取而不被掛起。
在操作系統中,使用優先級繼承算法解決優先級翻轉問題。優先級翻轉是指當一個高優先級任務H通過同步機制訪問同步資源時,該資源已被一低優先級任務L占有,而系統中還有中優先級的任務M在執行,造成L得不到調度,高優先級任務H就一直被阻塞,結果M先于H執行,優先級發生了翻轉,實時性難以得到保證。優先級繼承算法實現如下,高優先級任務H在等待低優先級的任務L占用的同步資源時,由操作系統把L的優先級提高到H的優先級,從而讓L以H的優先級參與調度,盡快執行并釋放資源,然后L的優先級調整到繼承前的值,此時H可獲得競爭資源而繼續執行,如下圖。
<優先級繼承示意圖>?
互斥量控制塊是操作系統用于管理互斥量的一個數據結構,由結構體os_mutex_t表示??刂茐K結構的詳細定義請見以下代碼:
struct os_mutex { os_ipc_object_t parent; /* 繼承自os_ipc_object 類*/ os_uint16_t value; /* 互斥量的值*/ os_uint8_t original_priority; /* 持有任務的原始優先級*/ os_uint8_t nested; /* 持有任務的持有次數*/ os_task_t *owner; /* 當前擁有互斥量的任務*/ };互斥量接口設計如下:
(1)創建互斥量?
(2)銷毀互斥量
(3)獲取互斥量
(4)釋放互斥量
信號量
信號量是一種輕型的用于解決任務間同步問題的內核對象,任務可以獲取或釋放它,從而達到同步或互斥的目的。
信號量初始化為大于0的整數,表示資源的數量,當一個任務申請到一個資源后將該整數減1,當該整數值為0時,所有試圖申請的任務都將處于阻塞狀態。在信號量上定義兩種操作:wait(獲取)和post(釋放)。當一個任務調用wait操作時,它要么得到資源然后將信號量減1,要么一直等下去。當有其他任務釋放資源,調用post在信號量上執行加1操作,阻塞等待的任務可以得到執行。
信號量控制塊結構的詳細定義如下:
信號量接口設計如下:
(1)創建信號量?
(2)銷毀信號量
(3)獲取信號量
(4)無等待獲取信號量
(5)釋放信號量
事件集
事件集可以實現一對多,多對多的同步。任務可以設計成為被一個事件組合喚醒,事件組合可以包含一個或者多個事件的“與”或“或”的關系。
系統使用一個32位無符號整型變量來表示這種事件集的關系,變量的每一位代表一個事件,也就是系統最多支持32個事件。通過“與”或“或”將一個或多個事件關聯起來,形成事件組合。通過“或”組合的事件集中的任何一個事件都可以喚醒任務;通過“與”組合的事件集需要所有事件都發生后才可以喚醒任務。
因為32位無符號整型的一個位記錄一種事件,無記錄次數功能,如果任務還未處理該事件時又發生同一個事件,其效果等同于只發送一次。
事件集控制塊結構的詳細定義如下:
事件集接口設計如下:
(1)動態創建事件集
(2)銷毀事件集
(3)發送事件
(4)接收事件集
?好啦,本次任務間同步就介紹到這啦,如果有想了解的內容可以在評論區留言交流哦~
總結
以上是生活随笔為你收集整理的任务间同步 | 信号量、互斥量和事件集的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 打开Adobe Premiere Pro
- 下一篇: TensorRT 推理时提示This c