一、消息隊列的基本概念
消息隊列消息隊列就是一個消息的鏈表。就是把消息看作一個記錄,並且這個記錄具有特定的格式以及特定的優先級。對消息隊列有寫權限的進程可以按照一定的規則添加新消息;對消息隊列有讀權限的進程則可以從消息隊列中讀出消息。
Linux采用消息隊列的方式來實現消息傳遞。這種消息的發送方式是:發送方不必等待接收方檢查它所收到的消息就可以繼續工作下去,而接收方如果沒有收到消息也不需等待。這種通信機制相對簡單,但是應用程序使用起來就需要使用相對復雜的方式來應付了。新的消息總是放在隊列的末尾,接收的時候並不總是從頭來接收,可以從中間來接收。
消息隊列是隨內核持續的並和進程相關,只有在內核重起或者顯示刪除一個消息隊列時,該消息隊列才會真正被刪除。因此系統中記錄消息隊列的數據結構
IPC標識符:每一個I
IPC
二、ipcs 命令
命令ipcs用於讀取System
ipcs
ipcs
ipcs
ipcs
內核中實現消息傳遞機制的代碼基本上都在文件ipc/msg.c中,消息隊列的主要調用有下面4個
(1)msgget:調用者提供一個消息隊列的鍵標
(2)msgsnd:向一個消息隊列發送一個消息,主要由sys_msgsnd執行。
(3)msgrcv:從一個消息隊列中收到一個消息,主要由sys_msgrcv執行。
(4)msgctl:在消息隊列上執行指定的操作。根據參數的不同和權限的不同,可以執行檢索、刪除等的操作,主要由sys_msgctl執行。
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
int msgget( key_t msgkey , int flag );
取得一個消息隊列的ID,如不存在則建立。
返回值: 成功時:消息隊列的ID
失敗時:-1
int msgsnd( int msqid , struct msgbuf *msgp , size_t msgsiz , int msgflag );
向消息隊列送消息
返回值: 成功時:0
失敗時:-1
msqid是消息隊列的ID,size_t msgsiz是結構體成員mdata的大小,msgflag與上一章所講的共享內存的flag起一樣的作用,不過,當這個參數為IPC_NOWAIT的時候,如果消息隊列已滿,則返回錯誤值。如果不為IPC_NOWAIT,在消息隊列已滿 的情況下,會一直等到消息隊列有空地方的時候再發送。
注意這里的這個 struct msgbuf *msgp 。要求的格式如下:
struct msgbuf
{
long mtype;
char mdata[256];
};
long mtype在這里我們用來保存本進程的PID。mdata則是保存要發送的數據。由於mdata的大小不一定(根據實際需要定義),所以這個結構體並沒有事先定義好。但是我們定義這個結構體的時候一定要遵循這個規定。你可以改的,只有mdata的大小,和結構體的名稱。盡量不要修改結構體成員的名稱和類型。實際上,根據mtype,我們還可以有所選擇地接受消息。這在下面將會談到。
int msgrcv( int msqid , struct msgbuf *msgp , size_t msgsiz , long msgtyp , int msgflag );
從消息隊列取得一個消息
返回值: 成功時:0
失敗時:-1
msqid , *msgp , msgsiz不用說了。long msgtyp是結構體msgbuf的mtype成員。msgflag與上述一樣。只不過為IPC_NOWAIT的時候,如果消息隊列是空的,則等到有消息可讀的時候再讀。當不為IPC_NOWAIT的時候,如果消息隊列是空的,則返回錯誤值(與字面上理解的有些相反)
下面這個鏈接幫助了我更好地理解了msgrcv 中的 long msgtyp這個參數和
struct msgbuf
{
long mtype;
char mdata[256];
};
里的long mtype這個結構體成員。
http://topic.csdn.net/u/20120131/15/235be4a4-3901-41ef-a577-55a5650efeeb.html?14521
同樣地,為了控制管理消息隊列,一樣有一個函數msgctl()如下:
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
int msgctl( int msqid , int cmd , struct msqid_ds *buf );
返回值: 成功時:0
失敗時:-1
cmd所指定的值與共享內存部分相同。
最后自己寫了一個利用消息隊列實現進程通信
基本思路:
我每次將A端發送消息時的消息類型標記為奇數,將B端發送的消息類型為偶數。
A端讀取消息類型為偶數的消息(也就是說是從B端發送過來的)
B端讀取消息類型為奇數的消息(也就是說是從A端發送過來的)
這個程序還有一些不完善的地方:
1.每個端口不能連續輸入,必須等對方輸入以后才 會顯示結果。這里我也不清楚怎么回事。gdb的調試還不太會,錯誤不太會找。希望高手指教,呵呵
2.沒有刪除消息隊列,下次打開時候還會殘留以前的消息
最后列出參考資料:
http://linux.chinaunix.net/techdoc/develop/2009/04/27/1109110.shtml
http://blog.sina.com.cn/s/blog_48c9576b0100joqg.html
http://blog.sina.com.cn/s/blog_48c9576b0100joqg.html
《Linux軟件工程師(c語言)實用版》