Linux進程間通信——03消息隊列

消息隊列:

消息:數據+類型  給數據一種特殊的標誌

隊列:先進先出,但其類似優先級隊列。

消息隊列提供了一個從一個進程向另外一個進程發送一塊數據的方法。每個數據塊都有一個特定的類型,接收方可以根
據類型來有選擇地選擇接收數據,而不一定像管道和命名管道那樣必須先進先出的方式接收數據。

消息隊列也有和管道一樣的不足,就是每個消息的最大長度是有上限的,每個消息隊列的總的字節數有上限,系統上消息隊列的總數也是有上限的。


函數:

頭文件:#include <sys/msg.h>

1、mesget系統調用:得到消息隊列標識符或創建一個消息隊列對象並返回消息隊列標識符。

      原型:int mesget (key_t key,int msgflg);

      參數:1)key是一個鍵值。輸入0:會建立新消息隊列。大於0的32位整數:視參數msgflg來確定操作。

                            2)與信號量semget函數參數一致。

       返回值:成功返回成功返回一個非負整數,即該消息隊列的標識碼;失敗返回-1。

當創建完成之後,內核數據結構msqid_ds也被創建並初始化。

2、msgsnd系統調用:將msg_ptr 消息寫入到標識符爲msqid的消息隊列

      原型:int msgsnd(int msqid,const void*msg_ptr ,size_t msg_sz, int msgflag)

      參數:1)消息隊列標識符  mesget函數返回值。

                            2)指向一個準備發送的消息。可以是任何類型的結構體,但第一個字段必須爲long類型,msgrcv根據此長整數確定消息的類型。

msgp定義的參照格式如下:

struct s_msg
{
    long type; /* 必須大於0,消息類型 */
    char mtext[256]; /*消息正文,可以是其他任何類型*/
} msg_ptr;

                            3)要發送消息的大小,不含消息類型佔用的4個字節,即mtext的長度

                            4)0:當消息隊列滿時,msgsnd將會阻塞,直到消息能寫進消息隊列

                               IPC_NOWAIT:當消息隊列已滿的時候,msgsnd函數不等待立即返回

                               IPC_NOERROR:若發送的消息大於size字節,則把該消息截斷,截斷部分將被丟棄,且不通知發送進程。

       返回值:成功返回0;失敗返回-1。

3、msgrcv系統調用:從標識符爲msqid的消息隊列讀取消息並存於msg_ptr中,讀取後把此消息從消息隊列中刪除

      原型:int msgrcv(int msqid,void*msg_ptr,size_t msg_sz,long int msgtype, int msgflg)

      參數:1)消息隊列標識符。

                            2)存放消息的結構體,結構體類型要與msgsnd函數發送的類型相同。

                            3)要接收消息的大小,不含消息類型佔用的4個字節。

                            4)0:接收第一個消息。

                                  >0:接收類型等於msgtyp的第一個消息。

                                  <0:接收類型等於或者小於msgtyp絕對值的第一個消息。

                            5)0: 阻塞式接收消息,沒有該類型的消息msgrcv函數一直阻塞等待。

                                  IPC_NOWAIT:如果沒有返回條件的消息調用立即返回,此時錯誤碼爲ENOMSG。

                                  IPC_EXCEPT:與msgtype配合使用返回隊列中第一個類型不爲msgtype的消息。

                                  IPC_NOERROR:如果隊列中滿足條件的消息內容大於所請求的size字節,則把該消息截斷,截斷部分將被丟棄。

       返回值:成功返回實際讀取到的消息數據長度;失敗返回-1

       msgrcv()解除阻塞的條件有以下三個:

                  ①    消息隊列中有了滿足條件的消息。②    msqid代表的消息隊列被刪除。③    調用msgrcv()的進程被信號中斷。

4、msgctl系統調用:獲取和設置消息隊列的屬性。

      原型:int msgctl(int msgid, int command ,struct msqid_ds*buf);

      參數:1)消息隊列標識符

                            2)IPC_STAT:獲得msgid的消息隊列頭數據到buf中

                                  IPC_SET:設置消息隊列的屬性,要設置的屬性需先存儲在buf中,可設置的屬性包括:msg_perm.uid、msg_perm.gid、msg_perm.mode以及msg_qbytes

                            3)buf:消息隊列管理結構體,請參見消息隊列內核結構說明部分

       返回值:成功返回0;失敗返回-1。

參考博文:https://blog.csdn.net/guoping16/article/details/6584024


Linux系統中有兩個宏定義:
                     MSGMAX, 以字節爲單位,定義了一條消息的最大長度。
                     MSGMNB, 以字節爲單位,定義了一個隊列的最大長度。

消息隊列優缺點:
                     優點:

                            1、可以實現任意進程間的通信,並通過系統調用函數來實現消息發送和接收之間的同步,無需考慮同步問題,方便;

                            2、獨立於進程的存在,不會像管道那樣,隨着進程結束而結束,它是Linux系統給的一個消息隊列表,是一個鏈表存在。

                            3、消息隊列克服了信號傳遞信息少,管道只能承載無格式字節流以及緩衝區大小受限等特點。

          缺點:信息的複製需要額外消耗CPU的時間,不適宜於信息量大或操作頻繁的場合

消息隊列應用場景:https://www.cnblogs.com/linjiqin/p/5720865.html


代碼實現:

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