訊息佇列是系統核心地址空間中的一個內部的鏈表。
訊息可以按照順序發送到隊列中,也可以以幾種不同的方式從隊列中讀取。
每一個訊息佇列用一個唯一的IPC標識符表示。
資料結構msgbuf,此資料結構可以說是訊息資料的模板,雖然此使用者結構需要使用者自己定義。
在中,此資料結構的定義為:struct msgbuf{long mtype;char request_id;struct cilent_info;}
這裡的訊息類型欄位和前面的一樣,但資料結構的其餘部分則由其他一個的兩個欄位所代替,而其中的一個還是另外一個結構。
這就體現了訊息佇列的靈活之處。msgget()用於建立一個新的訊息佇列,或者存取一個已經存在的訊息佇列。
msgsnd()系統調用用於向隊列發送一條訊息msgrcv()系統調用用於從訊息佇列中讀取一條訊息
這個今天下午複習了一下有關訊息佇列的知識,感覺就是它的識別度比較高,根據你的type來確定你要收發的資料,下面這個程式中編譯程msgtool後會產生一個a.out檔案
./a.out w 0 "hello"
再在另外一個終端下面輸入
./a.out r 0 這樣就能根據類型0來識別要寫入和輸出的資料
0可以換成其他的數字。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#define MAX_SEND_SIZE 80
struct mymsgbuf{//定義結構體
long mtype;
char mtext[MAX_SEND_SIZE];
};
void send_message(int qid,struct mymsgbuf *qbuf,long type,char *text);
void read_message(int qid,struct mymsgbuf *qbuf,long type);
void remove_queue(int qid);
void change_queue_mode(int qid,char *mode);
void usage(void);
int main(int argc,char **argv)
{
key_t key;
int msgqueue_id;
struct mymsgbuf qbuf;
if(argc==1)
usage();
//系統建立IPC通訊 (訊息佇列、訊號量和共用記憶體) 時必須指定一個ID值。通常情況下,該id值通過ftok函數得到。
key=ftok(".",'m');
if((msgqueue_id=msgget(key,IPC_CREAT|0666))==-1)
{
perror("msgget");
exit(1);
}
printf("message queue id = [%d] .\n",msgqueue_id);
switch(tolower(argv[1][0]))
{
case 's':
if(argc<4)
{
usage();
break;
}
send_message(msgqueue_id,&qbuf,atol(argv[2]),argv[3]);//把字串轉換成長整型數
break;
case 'r':
if(argc<3)
{
usage();
break;
}
read_message(msgqueue_id,&qbuf,atol(argv[2]));
break;
case 'd':
remove_queue(msgqueue_id);
break;
case 'm':
if(argc<3)
{
usage();
break;
}
default:usage();
}
return 0;
}
void send_message(int qid,struct mymsgbuf *qbuf,long type,char *text)
{
//給隊列發送訊息
printf("sending a message....\n");
qbuf->mtype=type;//賦數實值型別
strcpy(qbuf->mtext,text);
if((msgsnd(qid,qbuf,strlen(qbuf->mtext)+1,0))==-1)
{
perror("msgsnd");
exit(1);
}
}
void read_message(int qid,struct mymsgbuf *qbuf,long type)
{
printf("Reading a message...\n");
qbuf->mtype=type;
msgrcv(qid,qbuf,MAX_SEND_SIZE,type,0);
printf("Type: %1d Text:%s \n",qbuf->mtype,qbuf->mtext);
}
void remove_queue(int qid)
{
msgctl(qid,IPC_RMID,0);
}
void change_queue_mode(int qid,char *mode)
{
}
void usage(void)
{
fprintf(stderr,"msgtool -A utility for thinkering with msg queues \n");
fprintf(stderr,"USAGE:msgtool (s) end <type>> <>type> <>");
fprintf(stderr,"(r)");
fprintf(stderr,"(d)");
fprintf(stderr,"(m)");
exit(1);
}