程序間通訊——訊息佇列
什麼是訊息佇列?
訊息佇列就是提供了乙個程序向另乙個程序傳送乙個資料塊的方法,
其中每乙個資料塊都被認為有型別。接收者進、程接收的資料塊可以有不同的型別值,
通過傳送訊息來避免命名管道的同步和阻塞問題。
那麼訊息佇列和管道到底有什麼不同呢?
訊息佇列是基於訊息的,而管道是基於位元組流的;
訊息佇列的讀取不一定是先進先出的;
訊息佇列
是雙向通訊的,管道是單向通訊的;
訊息佇列可以在兩個沒有關係的程序之間通訊,而管道只能在兩個有血緣關係的程序之間通訊;
兩者又有一樣的不足:每個訊息的長度是有上限的,每個訊息的總位元組數是有限的,
系統中訊息佇列的總
數也是有
乙個上限的。
ipc(程序間通訊)物件的資料結構
核心會為每乙個ipc物件維護乙個資料結構
這兩個結構體只是讓大家了解一下,因為訊息佇列的底層使用鍊錶實現的,所以使用訊息佇列進行通訊,就是:乙個但程序在鍊錶鄰面放入結點,另外程序從鍊錶裡面取結點,但是如何保證每次取的結點就是我們想要的那個結點呢?其中ipc_perm結構體裡面,有乙個_key值,這個就是訊息佇列的唯一識別符號,我們在判斷訊息佇列時候,即使通過_key值來辨別訊息佇列的。
建立訊息佇列:msgget
int msgget(key_y key,int msgflage)
引數:①key: 此時的第乙個引數key是通過ftok函式建立
key_t ftok(const char* pathname,int proj_id);
pathname:帶路徑的檔名; proj_id:整數的工程號
返回值:成功返回key值,失敗返回-1
②msgflag:建立狀態
解釋:當把msgflag值傳:「ipc_creat」時候,呼叫msgget函式,系統就會為我們建立乙個新的消
息佇列,此時我們給出的key值已經存在的時候,此時就會把已經存在的訊息佇列的識別符號,
也就是:msgid傳過來;
當把msgflag值傳:「ipc_creat|ipc_excl」此時,當我們要建立的訊息佇列不存在時,就
會建立新的訊息佇列,當我們傳進來的key值已經存在的時候,此時就會報錯。
返回值:成功則返回建立的訊息佇列的msgid,失敗則返回-1
使用**來建立兩個程序之間的相互通訊——訊息佇列
實現之前,學習幾個相關的知識點:
①我們知道管道的生命週期是隨程序的,也就是程序結束的時候,管道也就結束了,但是訊息佇列生命週期
是隨核心的,也就是說,當我們在程序結束的時候,沒有通過指令或者**去銷毀訊息佇列,那麼這個消
息佇列就會一直存在,直到我們重啟或者關機。
②在系統中檢視存在的訊息佇列命令:
ipcs :檢視系統中當前所有ipc資源
ipcs -q:檢視系統中已建立的訊息佇列
ipcrm -q ××××:銷毀指定的訊息佇列,××××代表msgid
③實現原理:我們在comm.h中把函式進行宣告,
在comm.c中對函式進行實現,然後在建立:server.c和client.c,模擬兩個程序,使得兩個程序
相互通訊,在server.c和client.c中加入comm.h使用實現的方法
下面是**:comm.h:
comm.c:#ifndef _comm_h_
#define _comm_h_
#include#include#include#include#include"comm.c"
#define server_type 1
#define client_type 2
int creatmsgqueue();
int destorymsgqueue(int msgid);
int recvmsg(int msgid,int who,char* outmsg);
int sendmsg(int msgid,int who,const char* msg);
#endif
server.c:#include#include#include#include#include#define pathname "."
#define proj_id 0x6666
struct msgbuf;
static int commmsgqueue(int flags)
int msgid = 0;
if((msgid = msgget(_key,flags))<0)
return msgid;
}int creatmsgqueue()
int getmsgqueue()
int destorymsgqueue(int msgid)
}int sendmsg(int msgid,int who,const char* msg)
return 0;
}int recvmsg(int msgid,int who,char* outmsg)
strcpy(outmsg,_mb.mtext);
return 0;
}
client.c:#include#include "comm.h"
int main()
} destorymsgqueue(msgid);
return 0;
}
注意:在執行的時候,要注意幾點,因為訊息佇列在server.c建立的,所以要先去執行server.c檔案,#include#include "comm.h"
int main()
recvmsg(msgid,server_type,buf);//因為和server通訊,所以接收server型別的資料
printf("server say#%s\n",buf);//把收到的資料列印出來
} return 0;
}
然後,server.c是先去收訊息,收訊息的狀態是阻塞式,所以此時在沒有執行client.c的時候,
server.c是執行介面都沒有的,每次執行結束之後,我們都要用指令去把剛才建立的訊息佇列銷毀掉,
不然在下一次執行**的時候,就會出現問題,我就是在這塊弄了半天。
tip:限於編者水平,文章難免有缺漏之處,歡迎指正。
程序間訊息佇列通訊
要保證server能夠接收client的訊息,就必須保證server的生成的msg的識別符號是一樣的,也就是兩個用的key是必須一樣的。msglucy.c include include include include include include include include include ...
程序間通訊(訊息佇列)
在嵌入式linux應用開發中,linux程序通訊的方式有6種,分別是管道 pipe 及有名管道 named pipe 訊號 signal 訊息佇列 msg 共享記憶體 shm 訊號量 和套接字 socket 在這我就簡單的描述一下程序通訊中的資訊佇列 msg 首先,訊息佇列的實現有重要的幾步 1 建...
程序間通訊 訊息佇列
有三種稱作xsi ipc的ipc 訊息佇列 訊號量以及 共享記憶體。它們只見有很多的相似之處。訊息佇列是訊息的鏈結表,儲存在核心中,由訊息佇列識別符號表示。它不同於管道,其生命週期是隨核心的。訊息佇列提供了 一種從 乙個程序向另 乙個程序傳送 乙個資料塊的 方法。每個資料塊都被認為是有 乙個型別,接...