您好,登錄后才能下訂單哦!
這篇文章主要介紹了vxworks中Task如何計數信號量,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。
在<Task之二進制信號量>里提到過二進制信號量用來解決同步問題。下面看一個同步的例子
這段代碼很簡單,大致的意思就是每成功申請一次信號量,就打印一句話
啟動一個任務(t1)來調用這個函數:
可以看到t1阻塞到信號量semId上了。直接給它釋放一次信號量
任務(t1)打印了一句話,說明收到了一次信號量
接下來試試釋放兩次信號量,可以用Shell的命令repeat()
任務(t1)也打印了兩句話,說明收到了兩次信號量
接下來試試多次的
可以看到, repeat的次數大于2之后,任務(t1)都是只能收到兩次信號量
我們看看semGive()的操作流程
從上圖可以看到,repeat()第一次釋放信號量時,它會將阻塞狀態的t1置為就緒狀態。第二次釋放時,沒有任務阻塞了,于是將信號量置為有效(0->1),之后再釋放時,都是將信號量置有效(1->1)。直到repeat()執行完畢,就緒狀態的t1開始執行后續操作,出現第一次打印。然后又可以成功申請一次信號量(1->0),就有了第二次打印。這之后,信號量就又是無效的了,t1再次進入了阻塞狀態
這就是二進制信號量的特點,它是用來表示事件是否發生了,而不能表示事件發生的次數
如果需要記錄事件發生的次數呢?可以試試提高t1的優先級
不過VxWorks專門提供了用于計數的信號量: 計數信號量
semCCreate()用來動態創建計數信號量,semCInit()用來初始化靜態分配的信號量
initCount表示計數信號量的初值,因為是有符號整型值,其取值范圍是0-2147483647(0x0-0x7fffffff)
而具體的使用,與二進制信號量非常像
semTake()用來申請信號量,信號量無效時,引起阻塞,因此不能在ISR中使用
semGive()用來釋放信號量,在任務或ISR中都可以調用
與二進制信號量不同的是,計數信號量的值不是在0和1之間變化,而是用一個count來記錄具體數值。而且目前count的值可以超過2147483647(0x7fffffff)
超過之后,semGive()和semTake()還可以正常操作。只是show()操作時,只能看到低31位的值
從源碼里可以看到,只有count超過4294967295(0xffffffff)時,才會溢出。看來這應該是VxWorks的一個小bug了
Anyway,實際應用中,count的值不太可能那么大的。還是回到開始位置,把testSemB那個例子改了看看吧
這時候再多次釋放信號量,任務(t1)就可以收到多次了
同時,計數信號量也支持semFlush()操作,即它也是可以用于多任務同步的。
最后跑一個靜態初始化的例子吧
mySem是在編譯時就分配空間了,semCInit()里就不用在動態申請內存了
感謝你能夠認真閱讀完這篇文章,希望小編分享的“vxworks中Task如何計數信號量”這篇文章對大家有幫助,同時也希望大家多多支持億速云,關注億速云行業資訊頻道,更多相關知識等著你來學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。