程序通訊(訊息佇列)

2021-07-13 09:26:09 字數 3927 閱讀 4990

訊息佇列與管道不同的是,訊息佇列是基於訊息的,

而管道是基於位元組流的,且訊息佇列的讀取不一定是先入先出。訊息佇列與命名管道有一

樣的不足,就是每個訊息的最大長度是有上限的(msgmax),每個訊息佇列的總的位元組

數是有上限的(msgmnb),系統上訊息佇列的總數也有乙個上限(msgmni)。

ipc物件資料結構

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

struct ipc_perm ;

1.建立新訊息佇列或取得已存在訊息佇列

原型:int msgget(key_t key, int msg***);

引數:key:可以認為是乙個埠號,也可以由函式ftok生成。

msg***:

ipc_creat 如果ipc不存在,則建立乙個ipc資源,否則開啟操作。

ipc_excl:只有在共享記憶體不存在的時候,新的共享記憶體才建立,否則就產生錯誤。

如果單獨使用ipc_creat,***get()函式要麼返回乙個已經存在的共享記憶體的操作符,要

麼返回乙個新建的共享記憶體的識別符號。

如果將ipc_creat和ipc_excl標誌一起使用,***get()將返回乙個新建的ipc識別符號

;如果該ipc資源已存在,或者返回-1。

ipc_exel標誌本身並沒有太大的意義,但是和ipc_creat標誌一起使用可以用來保證

所得的物件是新建的,而不是開啟已有的物件。

2.向佇列讀/寫訊息

原型:msgrcv從佇列中取用訊息:ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int

msg***);

msgsnd將資料放到訊息佇列中:int msgsnd(int msqid, const void *msgp, size_t msgsz, int msg***);

引數:msqid:訊息佇列的標識碼

msgp:指向訊息緩衝區的指標,此位置用來暫時儲存傳送和接收的訊息,是乙個使用者可

定義的通用結構,形態如下:

struct msgstru;

msgsz:訊息的大小。

msgtyp:從訊息佇列內讀取的訊息形態。如果值為零,則表示訊息佇列中的所有訊息都

會被讀取。

msg***:用來指明核心程式在佇列沒有資料的情況下所應採取的行動。如果msg***和常

數ipc_nowait合用,則在msgsnd()執行時若是訊息佇列已滿,則msgsnd()將不會阻塞,而

會立即返回-1,如果執行的是msgrcv(),則在訊息佇列呈空時,不做等待馬上返回-1,並設定

錯誤碼為enomsg。當msg***為0時,msgsnd()及msgrcv()在佇列呈滿或呈空的情形時,採取

阻塞等待的處理模式。

3.設定訊息佇列屬性

原型:int msgctl ( int msgqid, int cmd, struct msqid_ds *buf );

引數:msgctl 系統呼叫對 msgqid 標識的訊息佇列執行 cmd 操作,系統定義了 3 種 cmd 操作

: ipc_stat , ipc_set , ipc_rmid

ipc_stat : 該命令用來獲取訊息佇列對應的 msqid_ds 資料結構,並將其儲存到 buf 指

定的位址空間。

ipc_set : 該命令用來設定訊息佇列的屬性,要設定的屬性儲存在buf中。

ipc_rmid : 從核心中刪除 msqid 標識的訊息佇列。

key_t鍵

system v ipc使用key_t值作為它們的名字,在redhat linux(後續驗證預設都在該平台下)下

key_t被定義為int型別

ftok函式

函式ftok把乙個已存在的路徑名和乙個整數標識得轉換成乙個key_t值,稱為ipc鍵:

# include # include key_t ftok(const char *pathname, int proj_id);

該函式把從pathname匯出的資訊與id的低序8位組合成乙個整數ipc鍵。

comm.h

1 #pragma once

2 #include3 #include4 #include5 #include6 #include7 #include8 #define _path_ ".tmp"

9 #define size 100

10 #define _proj_id 0x444

11 #define _client_ 2

12 #define _server_ 1

13 14 typedef struct _msginfo

15 msginfo;

19 int create_msg_set();

20 int get_msg_set();

21 int rec_msg_set(int,char*,long);

22 int send_msg_set(int,char*,long);

23 int destroy_msg_set(int);  

comm.c

1 #include "comm.h"

2 static int com_creat_msg_set(int flags)

3 10   int _msg_id=msgget(key,flags);

11   if(_msg_id<0)

12   

16 return _msg_id;

17 }

18 int creat_msg_set()

19 23 int get_msg_set()

24 29 

30 int rec_msg_set(int _msg_id,char* msg,long mtype)

31 40 strcpy(msg,_info.mtext);

41 return 0;

42 }

43 44 

45 int send_msg_set(int _msg_id,char *msg,long mtype)

46 58  return 0;

59 60 }

61 62 

63 int destroy_msg_set(int _msg_id)

64 70   return 0;

71 }

client.c

1 2 #include "comm.h"

3 int main()

4 21   destroy(_msg_id);

22   return 0;

23 }

server.c

1 #include "comm.h"

2 int main()

3 20   return 0;

21 }

makefile:

1 .phony:all

2 all:client server

3 client: client.c comm.c

4     gcc -o $@ $^

5 server:server.c comm.c

6     gcc -o $@ $^

7 .phony:clean

8 clean:

9     rm -f client server 

結果:[admin@localhost message]$ ./client

client:naihao

server:

woclient:

nihao

server:

aiclient: 

[admin@localhost message]$ ./server

client:naihaoserver:

wo ai ni

client:nihaoserver:

niaho

程序通訊 訊息佇列

訊息佇列的使用 建立開啟訊息佇列msgget 讀資料從佇列msgrcv 寫資料到佇列msgsnd 控制訊息佇列msgctl 目前主要有兩種型別的訊息佇列 posix訊息佇列以及系統v訊息佇列,系統v訊息佇列目前被大量使用 訊息佇列的核心持續性要求每個訊息佇列都在系統範圍內對應唯一的鍵值,所以,要獲得...

Linux程序通訊 訊息佇列

1.訊息佇列 訊息佇列也稱為報文佇列,訊息佇列是隨核心持續的,只有在核心重起或顯示刪除乙個訊息佇列時,該訊息佇列才會真正刪除 系統中記錄訊息佇列的資料結構struct ipc ids msg ids位於核心中,系統中所有訊息佇列都可以在結構msg ids中找到訪問入口 訊息佇列其實就是乙個訊息的鍊錶...

linux訊息佇列程序通訊

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