顧名思義,訊息佇列就是一些訊息的列表,使用者可以在訊息佇列中新增訊息和讀取訊息等。從這點上看,訊息佇列具有一定的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物件使用的控制方法和檔案系統非常類似。使用物件的引用標誌符作為資...