消息隊列是內核地址空間中的內部鏈表,經過linux內核在各個進程之間傳遞內容,消息順序地發送到消息隊列中,而且以幾種不一樣的方式linux
從隊列中獲取,每一個消息隊列能夠用IPC標識符惟一的進行標識,內核中的消息隊列是經過IPC的標識符來區別的,不一樣的消息隊列之間是數據結構
相互獨立的,每一個消息隊列中的消息又構成一個獨立的鏈表.ui
消息隊列中的數據結構spa
一、消息緩衝結構
向消息隊列發送消息時,必須組成合理的數據結構。Linux系統定義了一個模版數據結構msgbuf:
#include<linux/msg.h>
struct msgbuf{
long type;
char mtext[1];
}
其中type表示消息的類型,以正數表示。mtext是該消息的數據,並不必定就是char 類型,任意類型均可以的。
二、msqid_ds內核數據結構。
struct msqid_ds{
struct ipc_perm msg_perm;
time_t msg_stime;
time_t msg_rtime;
time_t msg_ctime;
unsigned long _msg_cbuyes;
..........
};
Linux內核中,每一個消息隊列都維護一個結構體,此結構體保存着消息隊列當前狀態信息,該結構體在頭文件linux/msg.h中定義。
三、ipc_perm內核數據結構
struct ipc_perm{
key_t key;
uid_t uid;
gid_t gid;
.......
};
結構體ipc_perm保存着消息隊列的一些重要的信息,好比說消息隊列關聯的鍵值,消息隊列的用戶id組id等。它定義在頭文件linux/ipc.h中
Linux的消息隊列(queue)實質上是一個鏈表, 它有消息隊列標識符(queue ID). msgget建立一個新隊列或打開一個存在的隊列; msgsnd向隊列末端
添加一條新消息; msgrcv從隊列中取消息, 取消息是不必定遵循先進先出的, 也能夠按消息的類型字段取消息.
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
int msgget(key_t key, int msgflg);
參數key是一個鍵值,由ftok得到;msgflg參數是一些標誌位。該調用返回與健值key相對應的消息隊列描述字,若是沒有消息隊列與健值key相對應,
而且msgflg中包含了IPC_CREAT標誌位或者key參數爲IPC_PRIVATE,那麼該調用將建立一個新的消息隊列。
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
int msgrcv(int msqid, struct msgbuf *msgp, int msgsz, long msgtyp, int msgflg);
該系統調用從msgid表明的消息隊列中讀取一個消息,並把消息存儲在msgp指向的msgbuf結構中。
msqid爲消息隊列描述字;消息返回後存儲在msgp指向的地址,msgsz指定msgbuf的mtext成員的長度(即消息內容的長度),msgtyp爲請求讀
取的消息類型,成功返回讀出消息的實際字節數,不然返回-1。
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
int msgsnd(int msqid, struct msgbuf *msgp, int msgsz, int msgflg);
向msgid表明的消息隊列發送一個消息,即將發送的消息存儲在msgp指向的msgbuf結構中,消息的大小由msgze指定。
對發送消息來講,有意義的msgflg標誌爲IPC_NOWAIT,指明在消息隊列沒有足夠空間容納要發送的消息時,msgsnd是否等待。成功返回0,不然
返回-1。
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
int msgctl(int msqid, int cmd, struct msqid_ds *buf);
該系統調用對由msqid標識的消息隊列執行cmd操做,共有三種cmd操做:IPC_STAT、IPC_SET 、IPC_RMID。
IPC_STAT:該命令用來獲取消息隊列信息,返回的信息存貯在buf指向的msqid結構中;
IPC_SET:該命令用來設置消息隊列的屬性,要設置的屬性存儲在buf指向的msqid結構中;可設置屬性包括:msg_perm.uid、msg_perm.gid、
msg_perm.mode以及msg_qbytes,同時,也影響msg_ctime成員。
IPC_RMID:刪除msqid標識的消息隊列;
如下示例程序在創建消息隊列後,打印其屬性,並在每次發送和接收後均查看其屬性,最後對消息隊列進行了修改:
該程序的執行結果以下: