進程間通信4

消息隊列的讀寫

寫消息隊列

  函數msgsnd用於向消息隊列發送(寫)數據.定義在頭文件sys/msg.h中

int msgsnd(int msqid, struct msgbuf *msgp, size_t msgsz, int magflg);
msqid: 函數向msgid標識的消息隊列發送了一個消息.
msgp:  msgp指向發送的消息.
msgsz: 要發送的消息的大小,不包含消息類型佔用的4個字節.
magflg: 操作標誌位.可以設置爲0或IPC_NOWAIT.
     如果爲0,則當消息隊列已滿的時候,msgsnd將會阻塞,直到消息可以寫進消息隊列. 如果爲IPC_NOWAIT,當消息隊列已滿時,msgsnd函數將不等待立即返回.

  msgsnd函數成功返回0,失敗返回-1.
  常見錯誤碼:
    EAGAIN:  消息隊列已滿.
    EIDRM:  消息隊列已被刪除.
    EACCESS: 無權訪問消息隊列.

讀消息隊列

  讀取消息的系統調用爲msgrcv(),定義在頭文件sys/msg.h中.

int msgrcv (int msqid, struct msgbuf *msgp, size_t msgsz, long int msgtyp, int msgflg);

msqid: 消息隊列描述符.
msgp: 讀取的消息存儲到msgp指向的消息結構中.
msgsz: 消息緩衝區的大小.
msgtyp: 爲請求讀取的消息類型.
msgflg: 操作標誌位.

 msgflg可以爲:
  IPC_NOWAIT: 若沒有滿足條件的消息,調用立即返回.
  IPC_EXCEPT: 與msgtyp配合使用,返回隊列中第一個類型不爲msgtyp的消息.
  IPC_NOERROR: 若隊列中滿足條件的消息內容大於所請求的msgsz字節,則把該消息截斷,截斷部分被丟棄.

獲取和設置消息隊列的屬性

消息對列的屬性保存在系統維護的數據結構msqid_ds中,可通過msgctl獲取或設置消息隊列的屬性.msgctl定義在頭文件sys/msg.h中.

int msgctl (int msqid, int cmd, struct msqid_ds *buf);

msgctl系統調用對msqid標識的消息隊列執行cmd操作.
 3種cmd操作:
  IPC_STAT: 獲取消息隊列對應的msqid_ds數據結構將其保存在buf指向的地址空間.
  IPC_SET: 設置消息隊列的屬性,要設置的屬性存儲在buf中.
  IPC_RMID: 從內核中刪除msqid標識的消息隊列.

消息隊列與命名管道的比較

和命名管道一樣,消息隊列進行通信的進程可以是不相關的進程,同時它們都是通過發送和接收的方式來傳遞數據的。在命名管道中,發送數據用write,接收數據用read,則在消息隊列中,發送數據用msgsnd,接收數據用msgrcv。而且它們對每個數據都有一個最大長度的限制。

消息隊列的優勢:
1、消息隊列也可以獨立於發送和接收進程而存在,從而消除了在同步命名管道的打開和關閉時可能產生的困難。
2、通過發送消息還可以避免命名管道的同步和阻塞問題,不需要由進程自己來提供同步方法。
3、接收程序可以通過消息類型有選擇地接收數據,而不是像命名管道中那樣,只能默認地接收。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章