15 ipc中的訊息佇列

2021-08-29 03:57:43 字數 4194 閱讀 9734

 訊息佇列提供了乙個從乙個程序向另外乙個程序傳送一塊資料的方法

 每個資料塊都被認為是有乙個型別,接收者程序接收的資料塊可以有不同的型別值

 訊息佇列也有管道一樣的不足,就是每個訊息的最大長度是有上限的(msgmax),每個訊息佇列的總的位元組數是有上限的(msgmnb),系統上訊息佇列的總數也有乙個上限(msgmni)

對比:管道:流管道 先進先出

訊息:有邊界可以後進入、先出來

訊息大小三大限制

cat /proc/sys/kernel/msgmax 最大訊息長度 限制

cat /proc/sys/kernel/msgmnb 訊息佇列總的位元組數

cat /proc/sys/kernel/msgmni 訊息條目數

	核心為每個ipc物件維護乙個資料結構

struct ipc_perm ;

struct msqid_ds ;

	#include 	#include 	#include 	int msgget(key_t key, int msg***);

 int msgctl(int msqid, int cmd, struct msqid_ds *buf);

 int msgsnd(int msqid, const void *msgp, size_t msgsz, int msg***);

 ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msg***);

 功能:用來建立和訪問乙個訊息佇列

 原型

 int msgget(key_t key, int msg***);

 引數

 key: 某個訊息佇列的名字

 msg***:由九個許可權標誌構成,它們的用法和建立檔案時使用的mode模式標誌是一樣的

 返回值:成功返回乙個非負整數,即該訊息佇列的標識碼;失敗返回-1

 功能:訊息佇列的控制函式

 原型

 int msgctl(int msqid, int cmd, struct msqid_ds *buf);

 引數

 msqid: 由msgget函式返回的訊息佇列標識碼

 cmd:是將要採取的動作,(有三個可取值)

 返回值:成功返回0,失敗返回-1

cmd:將要採取的動作(有三個可取值),分別如下:

 功能:把一條訊息新增到訊息佇列中

 原型

 int msgsnd(int msqid, const void *msgp, size_t msgsz, int msg***);

 引數

 msgid: 由msgget函式返回的訊息佇列標識碼

 msgp:是乙個指標,指標指向準備傳送的訊息,

 msgsz:是msgp指向的訊息長度,這個長度不含儲存訊息型別的那個long int長整型

 msg***:控制著當前訊息佇列滿或到達系統上限時將要發生的事情

 返回值:成功返回0;失敗返回-1

 msg***=ipc_nowait表示佇列滿不等待,返回eagain錯誤。

 訊息結構在兩方面受到制約。首先,它必須小於系統規定的上限值;其次,它必須以乙個long int長整數開始,接收者函式將利用這個長整數確定訊息的型別

 訊息結構參考形式如下:

struct msgbuf

 功能:是從乙個訊息佇列接收訊息

 原型

 ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msg***);

 引數

 msgid: 由msgget函式返回的訊息佇列標識碼

 msgp:是乙個指標,指標指向準備接收的訊息,

 msgsz:是msgp指向的訊息長度,這個長度不含儲存訊息型別的那個long int長整型

 msgtype:它可以實現接收優先順序的簡單形式

 msg***:控制著佇列中沒有相應型別的訊息可供接收時將要發生的事

 返回值:成功返回實際放到接收緩衝區裡去的字元個數,失敗返回-1

//開啟訊息佇列,若不存在,則報錯

#if 0

int test()

perror("msgget");

return -1;

} system("ipcs -q");

return 0;

}#endif

/* hzmct@u-64:/study/linuxtest/day06/ipc_queue$ ./dm01_msgbase

自己檢查錯誤, 訊息佇列不存在

msgget: no such file or directory

*/

//開啟訊息佇列,若存在,使用舊的,若不存在,則建立

#if 0

int test()

perror("msgget");

return -1;

} printf("建立訊息佇列成功\n");

return 0;

}#endif

//開啟訊息佇列,若存在,使用舊的,若不存在,則建立

//獲取訊息佇列的id

#if 0

int test()

perror("msgget");

return -1;

} printf("msgid:%d\n", msgid);

printf("建立訊息佇列成功\n");

return 0;

}#endif

//若 ipc_creat and ipc_excl 在一起。。。。

//若不存在,則建立

//開啟訊息佇列,若存在,則提示已經存在

//單獨使用ipc_excl沒有任何意義

#if 0

int test()

if (errno == eexist)

perror("msgget");

return -1;

} printf("msgid:%d\n", msgid);

printf("建立訊息佇列成功\n");

return 0;

}#endif

/*

ipc_private建立訊息佇列,只能在自己家族中使用

不能在沒有血緣關係的程序間用

當使用了 ipc_private,則 ipc_creat and ipc_excl不起作用

。 每次執行程式,msqid都不一樣

hzmct@u-64:~$ ipcs -q

------ message queues --------

key msqid owner perms used-bytes messages

0x00000000 32769 hzmct 666 0 0

0x00000000 65538 hzmct 666 0 0

0x00000000 98307 hzmct 666 0 0

0x00000000 131076 hzmct 666 0 0

*/#if 0

int test()

if (errno == eexist)

perror("msgget");

return -1;

} printf("msgid:%d\n", msgid);

printf("建立訊息佇列成功\n");

return 0;

}#endif

int main()

IPC 訊息佇列

include int msgget key t key,int msg 返回值 若成功,返回訊息佇列id 若出錯返回 1 與其他ipc機制一樣,需要提供乙個鍵值key來命名某個特定的訊息佇列。可通過ftok 來生成。msg 表示訊息佇列訪問許可權。可與兩個巨集配合進行操作 ipc creat 如果...

IPC 訊息佇列

訊息佇列可以認為是乙個訊息列表。執行緒可以往訊息佇列中放置訊息或者取出訊息。每個訊息都是一條記錄,由傳送者賦予乙個優先順序。乙個程序在往乙個訊息佇列中寫入訊息之前,不需要有某個程序在該佇列上等待訊息到達 這跟管道和fifo是相反的 訊息佇列具有隨核心的持續性,也就是說在核心重新啟動之前,不管發訊息的...

IPC之訊息佇列

訊息佇列缺點 1.如果程序建立了乙個訊息佇列,在該佇列中放入了幾則訊息,然後終止,但是該訊息佇列及其內容並不會被刪除。直到出現一下情況 某個程序呼叫msgrcv或 msgctl讀訊息或刪除訊息佇列,某個程序執行ipcrm 1 命令刪除訊息佇列,或由正在啟動的系統刪除訊息佇列。2.訊息佇列有大小限制,...