等待乙個訊號量, OSSemPend

2021-07-29 15:47:18 字數 1689 閱讀 3095

程式清單 l6.10是ossempend()函式的源**。它首先檢查指標pevent所指的任務控制塊是否是由ossemcreate()建立的[l6.10(1)]。如果訊號量當前是可用的(訊號量的計數值大於0)[l6.10(2)],將訊號量的計數值減1[l6.10(3)],然後函式將「無錯」錯誤**返回給它的呼叫函式。顯然,如果正在等待訊號量,這時的輸出正是我們所希望的,也是執行ossempend()函式最快的路徑。

如果此時訊號量無效(計數器的值是0),ossempend()函式要進一步檢查它的呼叫函式是不是中斷服務子程式[l6.10(4)]。在正常情況下,中斷服務子程式是不會呼叫ossempend()函式

的。這裡加入這些**,只是為了以防萬一。當然,在訊號量有效的情況下,即使是中斷服務子程式呼叫的ossempend(),函式也會成功返回,不會出任何錯誤。

如果訊號量的計數值為0,而ossempend()函式又不是由中斷服務子程式呼叫的,則呼叫ossempend()函式的任務要進入睡眠狀態,等待另乙個任務(或者中斷服務子程式)發出該訊號量(見下節)。ossempend()允許使用者定義乙個最長等待時間作為它的引數,這樣可以避免該任務無休止地等待下去。如果該引數值是乙個大於0的值,那麼該任務將一直等到訊號有效或者等待超時。如果該引數值為0,該任務將一直等待下去。ossempend()函式通過將任務控制塊中的狀態標誌.ostcbstat置1,把任務置於睡眠狀態[l6.10(5)],等待時間也同時置入任務控制塊中[l6.10(6)],該值在ostimetick()函式中被逐次遞減。注意,ostimetick()函式對每個任務的任務控制塊的.ostcbdly域做遞減操作(只要該域不為0)[見3.10節,時鐘節拍]。真正將任務置入睡眠狀態的操作在oseventtaskwait()函式中執行 [見6.03節,讓乙個任務等待某個事件,oseventtaskwait()][l6.10(7)]。

因為當前任務已經不是就緒態了,所以任務排程函式將下乙個最高優先順序的任務調入,準備執行[l6.10(8)]。當訊號量有效或者等待時間到後,呼叫ossempend()函式的任務將再一次成為最高優先順序任務。這時ossched()函式返回。這之後,ossempend()要檢查任務控制塊中的狀態標誌,看該任務是否仍處於等待訊號量的狀態[l6.10(9)]。如果是,說明該任務還沒有被ossempost()函式發出的訊號量喚醒。事實上,該任務是因為等待超時而由timetick()函式把它置為就緒狀態的。這種情況下,ossempend()函式呼叫oseventto()函式將任務從等待任務列表中刪除[l6.10(10)],並返回給它的呼叫任務乙個「超時」的錯誤**。如果任務的任務控制塊中的os_stat_sem標誌位沒有置位,就認為呼叫ossempend()的任務已經得到了該訊號量,將指向訊號量ecb的指標從該任務的任務控制塊中刪除,並返回給呼叫函式乙個「無錯」的錯誤**[l6.10(11)]。

程式清單 l6.10 等待乙個訊號量

void ossempend (os_event *pevent, int16u timeout, int8u *err)

os_enter_critical();

if (pevent->oseventtype != os_event_type_sem) else if (osintnesting > 0) else else {

ostcbcur->ostcbeventptr = (os_event *)0;                (11)

os_exit_critical();

*err = os_no_err;

傳送乙個訊號量, OSSemPost

程式清單 l6.11是ossempost 函式的源 它首先檢查引數指標pevent指向的任務控制塊是否是ossemcreate 函式建立的 l6.11 1 接著檢查是否有任務在等待該訊號量 l6.11 2 如果該任務控制塊中的.oseventgrp域不是0,說明有任務正在等待該訊號量。這時,就要呼叫...

C 實現乙個訊號量

訊號量有很多應用場景,事實上只要是生產者 消費者模型,一般都需要乙個訊號量來控制。posix介面是有pv訊號量api的。但c 標準沒有。下面是乙個pv訊號量的簡單實現。有些不熟悉條件變數的人或許產生下面的疑問 1 wait裡已經對mtx加鎖並阻塞了,notify那裡申請mtx的行為豈不是一直等待?條...

ucosii等待訊號量函式中pend前後怎樣執行

1 key等於0 1 2時,mun 還執行嗎?2 key 3時,mun 還執行嗎?void task1 task void p arg lcd showxnum 150,111,sync sem.ctr,3,16,0 ostimedlyhmsm 0,0,0,499,os opt time perio...