IPC下的雙向通訊 訊息佇列

2021-07-27 14:48:34 字數 3254 閱讀 9597

訊息佇列:

訊息佇列提供了一種從乙個程序向另乙個程序傳送乙個資料塊的方法。 每個資料塊都被認為是有乙個型別,接收者程序接收的資料塊可以有不同的型別值。我們可以通過傳送訊息來避免命名管道的同步和阻塞問題。訊息佇列與管道不同的是,訊息佇列是基於訊息的,而管道是基於位元組流的,且訊息佇列的讀取不一定是先⼊入先出。訊息佇列與命名管道有一樣的不足,就是每個訊息的最⼤大長度是有上限的(msgmax),每個訊息佇列的總的位元組數是有上限的(msgmnb),系統上訊息佇列的總數也有⼀乙個上限(msgmni)

ipc物件資料結構:

核心為每個ipc物件維護乙個資料結構(/user/include/linux/ipc.h)

struct kern_ipc_perm 

訊息佇列,共享記憶體和訊號量都有乙個共同的資料結構。

訊息佇列結構:

可以看到第乙個條目就是ipc的結構體,即是共有的,後面的都是訊息佇列所私有的成員。

訊息佇列使用鍊錶實現的。

所使用函式:

函式: key_t ftok(const char *filename, int proj_id);

通過檔名和專案號獲得system v ipc鍵值(用於建立訊息佇列、共享記憶體所用)

proj_id:專案號,不為0即可

返回:成功則返回鍵值,失敗則返回-1

函式: int msgget(key_t key, int msg***);

key:鍵值,當為ipc_private時新建一塊共享記憶體;

shm***:標誌。

ipc_creat:記憶體不存在則新建,否則開啟;

ipc_excl:只有在記憶體不存在時才建立,否則出錯。

返回:成功則返回識別符號,出錯返回-1

函式: int msgsnd(int msgid, const void *msgp, size_t sz, int ***);

向訊息佇列傳送訊息

msgid:通過msgget獲取

msgp:指向訊息內容的指標

sz:訊息內容的大小

***:處理方式;如為ipc_nowait時表示空間不足時不會阻塞

返回:成功則返回0,失敗返回-1

函式: int msgrcv(int msgid, void *msgp, size_t sz, long type, int ***);

從訊息佇列讀取訊息

msgid:通過msgget獲取

msgp:指向訊息內容的指標

sz:訊息內容的大小

type:指定接收的訊息型別;若為0則佇列第一條訊息將被讀取,而不管型別;若大於0則佇列中同型別的訊息將被讀取,如在***中設了msg_rxcept位將讀取指定型別的其他訊息;若小於0讀取絕對值小於type的訊息。

***:處理方式;

返回:成功返**到訊息長度,錯誤返回-1

函式: int msgctl(int msgid, int cmd, struct msgid_ds *buf);

msgid:通過msgget獲取

cmd:控制命令,如下:

ipc_stat:獲取訊息佇列狀態

ipc_set:改變訊息佇列狀態

ipc_rmid:刪除訊息佇列

buf:結構體指標,用於存放訊息佇列狀態

返回:成功返回與cmd相關的正數,錯誤返回-1

具體的實現過程如下:

comm.h

#ifndef _comm_h_

#define _comm_h_

#include#include#include#include#include#define pathname "."

#define proj_id 0x6666

#define server_type 1

#define client_type 2

#define size 128

struct msgbuf;

int creatmsgqueue();

int getmsgqueue();

int sendmsg(int msgid,long type,const char*_info);

int recvmsg(int msgid,long type,char out);

int destorymsgqueue(int);

#endif

comm.c

#include"comm.h"

int commmsgqueue(int flags)

int msg_id = msgget(_k,flags);

if(msg_id<0)

return msg_id;

}int creatmsgqueue()

int getmsgqueue()

int destorymsgqueue(int msgid)

}int sendmsg(int msgid,long type,const char*_info)

return 0;

}int recvmsg(int msgid,long type,char out)

strcpy(out,msg.mtext);

return 0;

}

client.c

#include"comm.h"

int main()

recvmsg(msgid,server_type,buf);

printf("server# %s\n",buf);

} return 0;

}

server.c

#include"comm.h"

int main()

} deseorymsgqueue(msgid);

return 0;

}

執行結果:

注意:訊息佇列存在後不可再次被建立

ipcs -q可檢視存在的訊息佇列

ipcrm -q +msgid 可刪除該訊息佇列

Linux程序通訊之訊息佇列的雙向通訊

include include include int msgget key t key,int msg 其中msg 表示生成訊息佇列的方式和許可權,一般使用的話,有三個常用引數,ipc creat ipc excl umask,ipc creat單獨使用時代表如果沒有此訊息佇列,那就生成乙個,如果...

程序間通訊 IPC 訊息佇列

訊息佇列是訊息的鏈結表,儲存在核心中,由訊息佇列識別符號標識。有足夠寫許可權的程序可往佇列中放置訊息,有足夠讀許可權的程序可從佇列中取走訊息。posix 和 system v 下的訊息佇列略有不同,主要體現在一下幾個方面 這裡我們以 posix 下的訊息隊列為例來進行講解。訊息佇列的建立 訊息佇列的...

程序間通訊 IPC 訊息佇列

訊息 可以簡單理解為型別 資料 訊息型別需大於等於1,0代表著不區分訊息型別,也可以認為是任何型別 struct mess 訊息佇列在同一型別上的訊息傳遞符合先進先出的規定,對於整個訊息佇列而言,類優先順序佇列 引用標頭檔案 include 建立 int msgget ket t key int f...