標籤:des blog http io ar os 使用 sp for
VxWorks處理序間通訊2 -- 訊號量一.訊號量的概念
是實現任務互斥、同步操作的主要機制。VxWorks提供的訊號量經過了高度最佳化,在所有任務間通訊機制中,速度最快。
二.訊號量的分類
Binary Semaphores(二進位):完成互斥、同步操作的最佳方式;速度最快,最常用。
Mutual Exclusion Semaphores(互斥):一種特殊的二進位訊號量,專門針對互斥操作進行了最佳化。
Counting Semaphores(計數):類似於二進位訊號量,可記錄訊號量釋放的次數,可監視同一資源上的多個執行個體。
三.Binary Semaphores(二進位訊號量)
Task經常會等待事件或需擷取資源。查詢(polling)在RealTime系統中原則上不允許,最好採用Pending,等待事件或資源。
狀態圖:
說明:
1.為某個資源調用semBCreate()建立一個binary semaphore 並規定:
SEM_Full (資源可用) SEM_Empty (資源不可用).
2.資源不可用時Task調用semTake()進入Pending直到semaphore被Given
相關函數:
[c-sharp] view plaincopy
-
SEM_ID semBCreate
-
(
-
int options, /* semaphore options */
-
-
SEM_B_STATE initialState /* initial semaphore state */
-
)
-
-
STATUS semTake
-
(
-
SEM_ID semId, /* 需要擷取的訊號量ID */
-
-
int timeout /* 逾時時間(tick)/no-wait/forever */
-
)
ISR(中斷服務程式)不能調用semTake()操作!
[c-sharp] view plaincopy
-
STATUS semGive
-
(
-
SEM_ID semId /* 需要釋放的訊號量ID */
-
)
[c-sharp] view plaincopy
-
semFlush()
應用方向:
1.互斥操作:是指不同任務可以利用訊號量互斥地訪問臨界資源。這種互斥的訪問方式比中斷禁止(interrupt disable) 與優先順序鎖定
(preemptive locks)兩種互斥方式具有更加精確的粒度。
互斥操作時初始狀態設為(SEM_FULL)可用。並在同一個Task中成對、順序調用semTake()、semGive()。
2.同步操作:是指一個任務可以利用訊號量控制自己的執行進度,使自己同步於一組外來事件。同步操作時初始狀態設為(SEM_EMPTY)不可用。在不同Task中分別單獨調用semTake()、semGive()。
四.Mutual Exclusion Semaphores(互斥訊號量)
互斥訊號量是一種特殊的二進位訊號量,它是針對使用二進位訊號量進行互斥操作時存在的一些問題設計的。互斥訊號量主要增加了對優先順序倒置、刪除安全以及遞迴訪問的處理。
狀態圖:
相關函數:
[c-sharp] view plaincopy
-
SEM_ID semMCreate
-
(
-
int options /* mutex semaphore options */
-
)
區別:
1.互斥訊號量只能用於互斥操作。
2.只能由已經擷取了互斥訊號量的任務去釋放它。
3.中斷服務程式(ISR)不可以釋放(semGive())互斥訊號量。
4.互斥訊號量不支援semFlush()操作。
應用方向:
1.避免優先順序倒置(Priority Inversion):
在中,task2等待task1的資源,於是處於Pend狀態,這時一個中等優先順序的task進來,並搶佔了task1的CPU,此時的表現是低優先順序task在高優先順序的task2前執行。這種現象就是先級倒置。
使用semId = semMCreate(SEM_Q_PRIORITY | SEM_INVERSION_SAFE);就可以避免倒置。
此時,task1的優先權提升與task2一樣,至到task2執行完成。
SEM_INVERSION_SAFE不能與SEM_Q_FIFO配對!
2.Deletion Safety(安全刪除)
使用:semId = semMCreate(SEM_Q_FIFO | SEM_DELETE_SAFE);可以實現安全刪除。
其實質是:在Task對互斥訊號量執行semTake()操作並成功佔有該訊號量之前,隱含執行了taskSafe()操作;在執行semGive()操作之後,隱含執行taskUnsafe()操作。
如果一個任務task1試圖刪除一個已經被保護起來的任務task2,task1則將被阻塞起來,直到task2解除保護(釋放掉具有刪除保護的互斥訊號量)才能完成刪除工作。
3.遞迴訪問
[c-sharp] view plaincopy
-
InitFun()
-
{
-
sem_ID = semMCreate(…);
-
}
-
-
funB()
-
{
-
semTake(sem_ID, SEM_FOREVER);
-
-
/*訪問臨界資源*/
-
-
semGive(sem_ID);
-
}
-
-
funA()
-
{
-
semTake(sem_ID, SEM_FOREVER);
-
-
/*訪問臨界資源*/
-
-
funB(); //遞迴訪問, 而不會死結
-
-
semGive(sem_ID);
-
}
五.Counting Semaphores(計數訊號量)
計數訊號量與二進位訊號量都可以用於任務之間的同步與互斥。其不同點在於,計數訊號量可記錄訊號量釋放的次數,可以用來監視某一資源的使用狀況。
狀態圖:
相關函數:
[c-sharp] view plaincopy
-
SEM_ID semCCreate
-
(
-
int options, /* semaphore option modes */
-
-
int initialCount /* initial count */
-
)
VxWorks處理序間通訊2 -- 訊號量