消息隊列是內核中的一個鏈表
用戶進程將數據傳輸到內核後,內核重新添加一些如用戶ID、組ID、讀寫進程的ID和優先級等相關信息後並打成一個數據包稱爲消息。允許一個或者多個進程往消息隊列中寫消息和讀消息,但一個消息只能被一個進程讀取,讀取完畢後自動刪除,消息隊列具有一定的FIFO的特性,消息可以按照順序發送到隊列中,也可以幾種不同的方式從隊列中讀取,每一個消息隊列在內核中用唯一的IPC標識ID表示
消息隊列的實現包括創建和打開隊列、發送消息、讀取消息和控制消息隊列四種操作
消息隊列的一個讀寫實例:
發消息程序:往一個消息隊列裏發送5條消息
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/msg.h>
typedef struct
{
long type;
int start;
int end;
}MSG;
int main(int argc,char **argv)
{
if(argc<2)
{
printf("usage :%s key\n",argv[0]);
exit(1);
}
key_t key=atoi(argv[1]);
printf("key:%d\n",key);
int msg_id;
msg_id=msgget(key,IPC_CREAT|IPC_EXCL|0777);
if(msg_id<0)
{
perror("msgget error");
}
printf("msq_id:%d\n",msg_id);
MSG m1={4,4,400};
MSG m2={2,2,200};
MSG m3={1,1,100};
MSG m4={6,6,600};
MSG m5={6,60,6000};
if(msgsnd(msg_id,&m1,sizeof(MSG)-sizeof(long),IPC_NOWAIT)<0)
{
perror("msgsnd error");
}
if(msgsnd(msg_id,&m2,sizeof(MSG)-sizeof(long),IPC_NOWAIT)<0)
{
perror("msgsnd error");
}
if(msgsnd(msg_id,&m3,sizeof(MSG)-sizeof(long),IPC_NOWAIT)<0)
{
perror("msgsnd error");
}
if(msgsnd(msg_id,&m4,sizeof(MSG)-sizeof(long),IPC_NOWAIT)<0)
{
perror("msgsnd error");
}
if(msgsnd(msg_id,&m5,sizeof(MSG)-sizeof(long),IPC_NOWAIT)<0)
{
perror("msgsnd error");
}
struct msqid_ds ds;
if(msgctl(msg_id,IPC_STAT,&ds)<0)
{
perror("msgctl error");
}
printf("msg total :%ld\n",ds.msg_qnum);
return 0;
}
取消息程序:
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/msg.h>
typedef struct
{
long type;
int start;
int end;
}MSG;
int main(int argc,char **argv)
{
if(argc<2)
{
printf("usage :%s key\n",argv[0]);
exit(1);
}
key_t key=atoi(argv[1]);
printf("key:%d\n",key);
long type=atoi("argv[2]");
printf("the type is %ld\n",type);
int msq_id;
msq_id=msgget(key,0777);
if(msq_id<0)
{
perror("msgget error");
}
printf("msg id :%d\n",msq_id);
MSG m;
if(msgrcv(msq_id,&m,sizeof(MSG)-sizeof(long),type,IPC_NOWAIT)<0)
{
perror("msgrcv error");
}
else
{
printf("the message type is %ld,start : %d end : %d\n",m.type,m.start,m.end);
}
struct msqid_ds ds;
if(msgctl(msq_id,IPC_STAT,&ds)<0)
{
perror("msgctl error");
}
printf("msg total :%ld\n",ds.msg_qnum);
return 0;
}