1. 程式人生 > >UCOS2:對於訊號量,互斥訊號量,事件標誌組

UCOS2:對於訊號量,互斥訊號量,事件標誌組

2.訊號量:
    至於訊號量,和互斥訊號量是用區別的,簡單來說(個人理解,歡迎糾正)就是互斥訊號量再同一時刻,任務得到互斥訊號量量後是獨佔共享資源的,在他沒有釋放訊號量之前,任何其他任務都是不能訪問共享資源的。而訊號量的不同在於。訊號量可以設定一個值,允許最多又幾個任務同時去訪問共享資源。比如我給他設定一個5,那麼對多就有5個任務能同時訪問共享資源。每個任務獲得訊號量的時候就把訊號量計數器減去1,這樣,再第五個任務獲取後,計數器是0.當第六個任務要去訪問的時候申請訊號量就只能等待了,等到之前的任務發一個訊號出來,這樣第六個任務才能去訪問共享資源。

互斥訊號量可以看成特殊情況下的訊號量,他的計數器就是0或者1,只在這兩個之間徘徊。

舉個例子(不一定恰當,歡迎糾正):
現在有很多串列埠擴充套件卡,一張卡能擴展出好幾個串列埠,比如說4個,這個擴充套件卡就是一個共享資源。現在定義一個訊號量semcom,初始給他4,那麼可以有4個任務去訪問這個資源,他每次就給這4個任務分配不同的串列埠。每個任務要訪問這個擴充套件卡就要去測試semcom看看他時候有訊號。這樣,前4個任務申請訊號後,訊號量計數器就等於0了,這樣,在第五個任務要去訪問擴充套件卡的時候,他也去測試這個semcom,發現訊號量無效,他只能等了~!等到之前的任務釋放一個串列埠為止,如果不用訊號量,那麼任務五可能就會去訪問擴充套件卡上的串列埠1,而串列埠1之前已經分配給了任務1了,~造成什麼後果就自己想想吧~~~~如果用互斥訊號量,那麼無疑浪費了資源,~~~那你就買個擴充套件1個串列埠的卡就行了~~你買個擴充套件4個的然後你用互斥訊號量~~~不是擺明再說你是富二代麼~~~

等待訊號的任務在有訊號以後也是按照等待列表中優先順序最高的任務先得到訊號處理。有關訊號量的具體資料結構參考事件控制塊ECB的內容,具體操作參考訊號量函式等。在此不做介紹
下面這個圖說明了以上的例子:(

3.事件標誌組:
    在理解訊號量和互斥訊號量的時候都可以類比,因為他們在ucos2裡面都通過相同的時間控制塊即ECB這個資料結構來實現,理解了一個就很好能看懂另外一個,設定更後面的郵箱和訊息佇列,也能和訊號量之類的類比來學習,他們都有通過ECB來維護。但是事件標誌組比較特別,他是ucos2所有這些核心事件裡面沒有用到ECB的。他有自己的做法。不太合群。什麼是事件標誌組?
    上面說的訊號量,互斥訊號量。都是用來同步任務對共享資源的訪問,防止衝突而設立的。事件標誌組----他是用來同步幾個任務,協調幾個任務工作而設立的。打個比方你現在要打個電話,打電話這個任務要執行,你必須有手機吧!那你要先執行買手機這個任務,你手機有了,沒話費~你也大不了吧~,也就是說打電話這個任務要等買手機這個任務和充話費這個任務都完成了以後你才能去開始打電話這個任務。事件標誌組就是用來標誌買手機或者充話費這兩個任務完成了沒有。完成了的話他們會相應的置位事件標誌組裡面的某些標誌位。那麼打電話這個任務。發現事件標誌組裡面買手機對應的位和充話費對應的位都置位了以後就明白,現在可以開始打電話了~!實際中比如你想要讀資料,那你肯定要等資料採集更新好了以後你去讀才有意義吧~所以資料採集和讀取資料這兩個任務也可以用事件標誌組來實現。當然,事件標誌組不一定只用於兩個任務之間,通過對標頭檔案的修改,可以讓事件標誌組達到32位,你可以用事件標誌組來協調多個任務的合理執行。達到你預期想達到的目的!事件標誌組就是專門幹這個活的。

    事件標誌組的結構比其他的會複雜一點。沒一個事件標誌組都維護這自己的一個等待佇列的雙向連結串列。每個事件標誌組的節點裡面都有一個指標和相應的任務控制塊TCB一一對應。至於事件標誌組的具體實現方法,可以自己去看看原始碼。只要
懂得一些淺顯的雙向連結串列的知識,大概理解他的運作機制不會很難。
    下面這幅圖大概反應出了事件標誌組是如何協調任務工作的:


終於要完了~~總的來說,到目前為止,都還能大概理解ucos的每個模組的實現機理。但是是不是真的懂了自己不敢說。畢竟要等能真的自己動手一直,再ucos2系統上開發出應用那樣才能真的算懂了。也知道到那個時候,才有可能能對其有更深的理解。個人認為初看ucos2的時候只要能有一些基本的資料結構基礎如線性表,堆疊,佇列,單鏈表,雙鏈表之類的就差不多。在看的過程中慢慢體會作者的思想和學習別人的程式設計思路才是最重要的。
以上純屬個人愚見,歡迎和大家一起探討。本人也乃小小菜一個~~O(∩_∩)O