信號量-郵箱-消息隊列的區別


為什么要用: 
任務間的通信可以通過全局變量或者信號量來完成。全局變量雖然可以承載通信的內容,但是接收方無法意識到信息的到達,除非發送方向接收方發送一個信號量,或者接收方不斷該全局變量;信號量可以立即使接收方知道某個事件的發生,但無法傳遞具體內容。用信號量進行通信就像我們只撥通別人的手機而不與之通話;用消息隊列或者郵箱進行通信則可達到既 撥通別人的手機又與之通話的效果。換句話說,消息隊列和郵箱可以及時傳送事件的內容。

 郵箱通信的機理: 
發送方通過內核服務把一封郵件投遞到郵箱,內核完成投遞任務后通知等待列表中的接收方收取郵件。在整個投遞過程中,內核充當了郵遞員的角色。這里的“郵件”通常是一個指針,接收方可以通過該指針獲取郵件內容。

 郵箱的基本操作: 
內核通常提供如下的郵箱服務:初始化郵箱的內容。郵箱最初可以包含或者不包含郵件。把郵件發送到郵箱(post)。如果郵箱已滿,則返回錯誤信息
(OS_MBOX_FULL)。以“掛起”方式接收郵件(pend)。如果郵箱為空,則把取信者掛起;若超過一定時間郵箱仍為空,則返回超時信息。 
以“非掛起”方式接收郵件(accept)。如果郵箱為空,則返回一個空指針。 當希望一次性向某個任務發送多則消息時,郵箱就有點見肘了。因為一個郵箱只能裝一封信。把多上郵箱集中到一起管理和使用就變成了消息隊列,所以消息隊列的操作和郵箱很相似。可以簡單地認為,消息隊列是郵箱數組。 如果發送者是一對一的方式發送郵件,則等待列表中的優先級最高的任務將獲取郵件;如果是以廣播的方式發送郵件,則等待該郵件的所有任務將獲得此郵件.

消息隊列使用步驟:

 1.建立一個指向消息數組的指針和數組的大小,該指針數組必須申明為void類型,如下:
     void *MessageStorage[size]
 
2. 聲明一個OS_EVENT類型的指針指向生成的隊列,如下:
    OS_EVENT *QSem;
 
3.OSQcreate()函數創建消息隊列,如下:
  QSem =  OSQcreate(&MyArrayOfMsg[0],SIZE);
4.等待消息隊列中的消息,OSQPend()
 
5. 向隊列發送一條消息(FIFO),OSQPost();
 
6.1 向隊列發送一條消息(LIFO),OSQPostFront()
 
6.2 向消息隊列發送一則消息(LIFO或者FIFO)
  INT8U OSQPostOpt (OS_EVENT *pevent, void *msg, INT8U opt)
 
7、 無等待的從消息隊列中獲得消息,OSQAccept()
 
8、 清空消息隊列 INT8U OSQFlush (OS_EVENT *pevent)
 
9、 獲取消息隊列的狀態,OSQQuery()


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM