消息隊列是一個存放在內核中的消息鏈表,由消息隊列標識符標識。
向消息隊列發送消息時,必須組成合理的數據結構。Linux系統定義了一個模板數據結構msgbuf:
#include <linux/msg.h>
struct msgbuf{
long mtype;
char mtext[1];
};
mtype字段代表消息類型。mtext字段指消息內容。
消息隊列是隨着內核的存在而存在的,每個消息隊列在系統範圍內對應唯一的鍵值。要或得一個消息隊列的描述符,只需提供該消息隊列的鍵值即可,該鍵值通常由函數ftok返回。該函數原型:
#include <sys/types.h>
#include <sys/ipc.h>
key_t ftok(const char *pathname,int proj_id);
ftok函數根據pathname和proj_id這兩個參數生成唯一的鍵值。pathname在系統中一定要存在且進程有權訪問,參數proj_id的取值範圍是1~255。執行成功會返回一個鍵值,失敗返回-1。
ftok返回的鍵值可以提供給函數msgget。msgget()根據這個鍵值創建一個新的消息隊列或訪問一個已存在的消息隊列。msgget函數的原型:
#include <sys/msg.h>
int msgget(key_t key, int msgflg);
參數key即爲ftok函數的返回值。msgflg是標誌參數,一般取值IPC_CREAT,表示創建一個消息隊列。
創建消息隊列後,就可以對消息隊列進行讀寫了。函數msgsnd用於向消息隊列發送(寫)數據。
#include <sys/msg.h>
int msgsnd(int msgid, struct msgbuf *msgp, size_t msgsz, int msgflg);
上述函數向msgid標識的消息隊列發送一個消息msgp。msgsz是消息的大小。msgflg爲操作標誌位。msgsnd函數成功返回0,失敗返回-1。
以下程序演示如何向消息隊列發送消息:
#include <stdio.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#define BUF_SIZE 256
#define PROJ_ID 32
#define PATH_NAME "." //當前路徑
int main(void)
{
/*用戶自定義消息緩衝*/
struct mymsgbuf {
long msgtype;
char ctrlstring[BUF_SIZE];
} msgbuffer;
int qid; /*消息隊列標識符*/
int msglen;
key_t msgkey;
/*獲取鍵值*/
if((msgkey = ftok (PATH_NAME, PROJ_ID)) == -1)
{
perror ("ftok error!\n");
exit (1);
}
/*創建消息隊列*/
if((qid = msgget (msgkey, IPC_CREAT|0660)) == -1)
{
perror ("msgget error!\n");
exit (1);
}
/*填充消息結構,發送到消息隊列*/
msgbuffer. msgtype = 3;
strcpy (msgbuffer.ctrlstring , "Hello,message queue");
msglen = sizeof(msgbuffer) - 4; //要發送的消息大小,不包含消息類型佔用的4個字節
if(msgsnd (qid, &msgbuffer, msglen, 0) == -1)
{
perror ("msgget error!\n");
exit (1);
}
exit(0);
}
運行上述程序,即向消息隊列放入了一條消息,可以通過ipcs命令查看,執行結果如下: