linux 訊息佇列

2021-06-18 11:52:27 字數 4074 閱讀 7876

顧名思義,訊息佇列就是一些訊息的列表,使用者可以在訊息佇列中新增訊息和讀取訊息等。從這點上看,訊息佇列具有一定的fifo特性,但是它可以實現訊息的隨機查詢,比fifo具有更大的優勢。同時,這些訊息又是存在於核心中的,由「佇列id」來標識。

訊息佇列的實現包括建立或開啟訊息佇列、新增訊息、讀取訊息和控制訊息佇列4種操作,其中建立或開啟訊息佇列使用的函式是msgget(),這裡建立的訊息佇列的數量會受到系統訊息佇列數量的限制;新增訊息使用的函式是msgsnd(),它把訊息新增到已開啟的訊息佇列末尾;讀取訊息使用的函式是msgrcv(),它把訊息從訊息佇列中取走,與fifo不同的是,這裡可以取走指定的某一條訊息;控制訊息佇列使用的函式是msgctl(),它可以完成多項功能。

表1列舉了msgget()函式的語法要點。

表1 msgget()函式語法要點

所需標頭檔案

#include

#include

#include

函式原型

int msgget(key_t key, int msg***)

函式傳入值

key:訊息佇列的鍵值,多個程序可以通過它訪問同乙個訊息佇列,其中有個特殊值ipc_private,用於建立當前程序的私有訊息佇列

msg***:許可權標誌位

函式返回值

成功:訊息佇列id

出錯:-1

表2列舉了msgsnd()函式的語法要點。

表2 msgsnd()函式語法要點

所需標頭檔案

#include

#include

#include

函式原型

int msgsnd(int msqid, const void *msgp, size_t msgsz, int msg***)

函式傳入值

msqid:訊息佇列的佇列id

msgp:指向訊息結構的指標,該訊息結構msgbuf通常如下。

struct msgbuf

msgsz:訊息正文的位元組數(不包括訊息型別指標變數)

msg***

ipc_nowait:若訊息無法立即傳送(如當前訊息佇列已滿),函式會立即返回

0:msgsnd呼叫阻塞直到傳送成功為止

函式返回值

成功:0

出錯:-1

表3列舉了msgrcv()函式的語法要點。

表3 msgrcv()函式語法要點

所需標頭檔案

#include

#include

#include

函式原型

int msgrcv(int msgid, void *msgp, size_t msgsz, long int msgtyp, int msg***)

函式傳入值

msqid:訊息佇列的佇列id

msgp:訊息緩衝區,同msgsnd()函式的msgp

msgsz:訊息正文的位元組數(不包括訊息型別指標變數)

msgtyp

0:接收訊息佇列中第乙個訊息

大於0:接收訊息佇列中第乙個型別為msgtyp的訊息

函式傳入值

小於0:接收訊息佇列中第乙個型別值不小於msgtyp絕對值且型別值最小的訊息

msg***

msg_noerror:若返回的訊息比msgsz位元組多,則訊息就會截短到msgsz位元組,且不通知訊息傳送程序

ipc_nowait:若在訊息佇列中並沒有相應型別的訊息可以接收,則函式立即返回

0:msgsnd()呼叫阻塞直到接收一條相應型別的訊息為止

函式返回值

成功:0

出錯:-1

表4列舉了msgctl()函式的語法要點。

表4 msgctl()函式語法要點

所需標頭檔案

#include

#include

#include

函式原型

int msgctl (int msgqid, int cmd, struct msqid_ds *buf )

函式傳入值

msqid:訊息佇列的佇列id

cmd:命令引數

ipc_set:設定訊息佇列的資料結構msqid_ds中的ipc_perm域(ipc操作許可權描述結構)值,這個值取自buf引數

ipc_rmid:從系統核心中刪除訊息佇列

buf:描述訊息佇列的msqid_ds結構型別變數

函式返回值

成功:0

出錯:-1

下面的例項體現了如何使用訊息佇列進行兩個程序(傳送端和接收端)之間的通訊,包括訊息佇列的建立、訊息傳送與讀取、訊息佇列的撤銷和刪除等多種操作。

訊息傳送端程序和訊息接收端程序間不需要額外實現程序間的同步。在該例項中,傳送端傳送的訊息型別設定為該程序的程序號(可以取其他值),因此接收端根據訊息型別來確定訊息傳送者的程序號。注意這裡使用了fotk()函式,它可以根據不同的路徑和關鍵字產生標準的key。訊息佇列傳送端的**如下:

/* msgsnd.c */

#include

#include

#include

#include

#include

#include

#include

#define buffer_size 512

struct message

;int main()

/* 建立訊息佇列 */

if ((qid = msgget(key, ipc_creat|0666)) == -1)

printf("open queue %d\n",qid);

while(1)

msg.msg_type = getpid();

/* 新增訊息到訊息佇列 */

if ((msgsnd(qid, &msg, strlen(msg.msg_text), 0)) < 0)

if (strncmp(msg.msg_text, "quit", 4) == 0)

}exit(0);

} 訊息佇列接收端的**如下:

/* msgrcv.c */

#include

#include

#include

#include

#include

#include

#include

#define buffer_size 512

struct message

;int main()

/* 建立訊息佇列 */

if ((qid = msgget(key, ipc_creat|0666)) == -1)

printf("open queue %d\n", qid);

doprintf("the message from process %d : %s", msg.msg_type, msg.msg_text);

} while(strncmp(msg.msg_text, "quit", 4));

/* 從系統核心中移走訊息佇列 */

if ((msgctl(qid, ipc_rmid, null)) < 0)

exit(0);

} 以下是程式的執行結果,輸入「quit」則兩個程序都將結束。

$ ./msgsnd

open queue 327680

enter some message to the queue:first message

enter some message to the queue:second message

enter some message to the queue:quit

$ ./msgrcv

open queue 327680

the message from process 6072 : first message

the message from process 6072 : second message

the message from process 6072 : quit

本文選自華清遠見嵌入式培訓教材《從實踐中學嵌入式linux應用程式開發》

linux訊息佇列 Linux訊息佇列

訊息佇列,unix的通訊機制之一,可以理解為是乙個存放訊息 資料 容器。將訊息寫入訊息佇列,然後再從訊息佇列中取訊息,一般來說是先進先出的順序。可以解決兩個程序的讀寫速度不同 處理資料速度不同 系統耦合等問題,而且訊息佇列裡的訊息哪怕程序崩潰了也不會消失。最簡單的訊息記憶體的使用流程 ftok函式生...

linux訊息佇列

訊息佇列是核心位址空間中的內部鍊錶,每個訊息佇列都在系統範圍內對應唯一的鍵值,所以,要獲得乙個訊息佇列的描述字,只需提供該訊息佇列的鍵值即可。1 訊息緩衝區結構 存放訊息資料的模板,可在基本定義的基礎上自己定義 在include linux msg.h中宣告,描述如下 struct 可以定義自己的例...

linux 訊息佇列

一 訊息佇列的基本概念 訊息佇列 也叫做報文佇列 是unix系統v版本中3種程序間通訊機制之一。另外兩種是訊號燈和共享記憶體。這些ipc機制使用共同的授權方法。只有通過系統呼叫將標誌符傳遞給核心之後,程序才能訪問這些資源。這種系統ipc物件使用的控制方法和檔案系統非常類似。使用物件的引用標誌符作為資...