程序通訊(四) 訊息佇列

2021-08-15 13:10:54 字數 2141 閱讀 4565

訊息佇列和管道很像。但它比起管道不需要固定程序的唯讀和只寫,通訊間的程序都可以讀寫,並且支援多個程序。

而訊息佇列傳送的訊息 實際是乙個訊息型別和實際的訊息。訊息型別是什麼?它其實是乙個長整型數字,具體多少完全由使用者來定義,為的是讀訊息時可以根據這個型別來調整讀取的優先順序順序。

所以說訊息佇列傳送的是資料塊,一般傳送的訊息就定義為以下的結構體。

到時候讀取訊息的時候,不必像管道一樣必須讀第乙個,假如有加急訊息的話,讀取函式中可以取加急訊息的型別,這樣的話就會優先讀取相同型別的第乙個訊息,比如56型別的。

訊息佇列的具體使用

這裡要四個函式

1.int msgget(key_t key,int msg***);

和訊號量差不多的獲取函式,不過比起訊號量獲取後還要semctl初始值來說,第一次獲取訊息佇列在此函式第二個引數加|ipc_creat 就直接建立新的佇列,不用進行初始化。key值仍為使用者隨意定義的值,第二個就是許可權 加  ipc_creat等巨集(可選),返回值-1表示失敗,成功返回識別符號msgid。

2.int msgsnd(int msgid,const void *msg_ptr,size_t msg_sz,int msgflag)

第乙個引數為msgget函式標返回的識符,無需多說。

第二個就是我們要傳送的訊息的指標,就是上面定義的那個  訊息型別+實際訊息 的結構體指標。

第三個引數就是傳送的實際訊息的長度,即從第二個引數指標後跳過乙個long型別長度開始取內容。

第四個引數是一些巨集,控制訊息佇列滿了或者超過系統範圍的一些情況,目前我們基礎的都寫0就好。

3.int msgrcv(int msgid,void *msg_ptr,size_t msg_sz,long int type,int msg***);

前三個引數和msgsnd的前三個差不多,不過值得注意的是這裡的第二個引數是要接收訊息的指標,即自己定義的接受訊息緩衝區結構體的指標。

第四個引數就比較有意思了,也算是訊息佇列的核心用法吧,這裡接收的訊息就會按第四個引數裡long型type值去接受,即假如訊息佇列裡有乙個1234型別的訊息在中間,我要是第四個引數就寫1234,那麼就會優先接收到那個1234型別的訊息,不像管道一樣,必須先接收隊頭的訊息。還有幾個用法就是,如果寫成0,那麼就會·按著訊息佇列的順序讀訊息。如果寫成-n,那麼只會讀型別小於等於n的訊息

第五個引數也是一些巨集,處理訊息佇列中沒有第四個引數的值的型別的情況。一般我們也取0吧。

最後返回值-1表示失敗,成功返回第二個引數接受到的位元組數。

4.int msgctl(int msgid ,int command,struct msgid_ds buf);

和其他方式ipc的控制函式一樣,第二個引數三個值

ipc_stat, ipc_set, ipc_rmid

當第二個引數為ipc_rmid,表示要刪除訊息佇列,可以無視第三個引數,設為0就好。

至於ipc_stat, ipc_set

前者是第三個引數的結構體設為當前的訊息佇列關聯值。

後者是把訊息佇列的關聯值設為第三個引數結構體裡的值。

第三個引數的結構體就是一些使用者 組 ,訪問許可權之類的東西。

最後還是用一道題來示範下用法吧。

題目如下,a程序負責輸入型別和資料,bc程序分別負責讀取型別為1000和2000的資料。

其實bc可以寫成乙份**,在main函式傳參分情況討論就好

a程序**:

bc程序**:

結果如下:

程序間通訊(四) 訊息佇列

訊息佇列 訊息佇列提供了一種從 個程序向另 個程序傳送 個資料塊的 方法。每個資料塊都被認為是有 個型別,接收者程序接收的資料塊可以有不同的型別值。可以通過傳送訊息來避免命名管道的同步和阻塞問題。特點 基於訊息 是用鍊錶實現的 生命週期隨核心 每個訊息的最 大長度是有上限的 msgmax 每個訊息佇...

程序通訊(訊息佇列)

訊息佇列與管道不同的是,訊息佇列是基於訊息的,而管道是基於位元組流的,且訊息佇列的讀取不一定是先入先出。訊息佇列與命名管道有一 樣的不足,就是每個訊息的最大長度是有上限的 msgmax 每個訊息佇列的總的位元組 數是有上限的 msgmnb 系統上訊息佇列的總數也有乙個上限 msgmni ipc物件資...

程序通訊 訊息佇列

訊息佇列的使用 建立開啟訊息佇列msgget 讀資料從佇列msgrcv 寫資料到佇列msgsnd 控制訊息佇列msgctl 目前主要有兩種型別的訊息佇列 posix訊息佇列以及系統v訊息佇列,系統v訊息佇列目前被大量使用 訊息佇列的核心持續性要求每個訊息佇列都在系統範圍內對應唯一的鍵值,所以,要獲得...