消息队列 就是消息的一个链表,它允许一个或多个进程向它写消息,一个或多个进程从中读消息。具有一定的FIFO的特性,但是可实现消息的随即查询。这些消息存在于内核中,由队列ID来标识。
消息队列的实现包括创建和打开队列、添加消息、读取消息和控制消息队列这四种操作:
1)msgget:创建和打开消息队列,其消息数量受消息系统限制
2)msgsnd:添加消息,将消息添加到消息队列的尾部
3)msgrcv:读取消息,从消息队列中取走消息
4)msgctl:控制消息队列
int msgget()函数
所需头文件:#include<sys/types.h> #include<sys/ipc.h> #include<sys/shm.h>
函数原型:int msgget((key_t),key,int flag)
函数传入值:key:返回新的或已有队列的ID,IPC_PRIVATE flag:
函数返回值:成功:消息都列ID 出错:-1
int msgsnd()函数
所需头文件:#include<sys/types.h> #include<sys/ipc.h> #include<sys/shm.h>
函数原型:int nsgsnd(int msgid,const void* ptr,size_ t size,int flag)
函数传入值:msgid:消息队列的队列ID
ptr:指向消息结构的指针,该消息 结构为
struct msgbuf{
long mytype;//消息类型
char mytext[];//消息正文
}
size:消息的字节数,不要以 null结尾
flag:IPC_NOWAIT若消息并没有立即发送而调用进程立即返回
0:msgsnd调用阻塞直到条件满足为止
函数返回值:成功 0 失败 -1
int msgrcv()函数
函数原型:
int msgrcv(int msgid,struct msgbuf*msgp,int size,long msgtype,int flag)
函数传入值:
msgid:消息队列的id
msgp:消息缓冲区
size:消息的字节数
Msgtype:0:接受队列中的第一个消息;大于0:接收消息队列中第一个类型为msgtype的消息;小于0:接收消息队列中的第一个类型值不小于msgtype绝对值且类型值又最小的消息
flag:
函数返回值:成功 0 失败-1
//msg_send.c
#include<stdio.h>
#include<string.h>
#include<errno.h>
#include<unistd.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/msg.h>
#define MAX_TEXT 512
struct my_msg_st
{
long int my_msg_type;//消息类型,msgrcv()可接受指定类型消息
char some_text[MAX_TEXT];
};
int main()
{
int running = 1;
struct my_msg_st some_data;
int msgid;
char buffer[BUFSIZ];
msgid=msgget((key_t)1234,0666|IPC_CREAT);//创建打开队列
if(msgid==-1)
{
fprintf(stderr,"msgget fialed with error:%d\n",errno);
exit(1);
}
while(running)
{
printf("Enter some text:");
fgets(buffer,BUFSIZ,stdin);//将要输入的内容保存到缓冲区
some_data.my_msg_type=1;//初始化消息类型
strcpy(some_data.some_text,buffer);//初始化消息内容
//添加到消息队列
if(msgsnd(msgid,(void*)&some_data,MAX_TEXT,0)==-1)
{
fprintf(stderr,"msgsnd failed\n");
exit(1);
}
if(strncmp(buffer,"end",3)==0)
{
running=0;
}
}
}
//msg_rev.c
#include<stdio.h>
#include<string.h>
#include<errno.h>
#include<unistd.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/msg.h>
#define MAX_TEXT 512
struct my_msg_st
{
long int my_msg_type;//消息类型,msgrcv()可接受指定类型消息
char some_text[MAX_TEXT];
};
int main()
{
int msgid;
int running=1;
struct my_msg_st some_data;
long int msg_to_receive=0;
msgid=msgget((key_t)1234,0666|IPC_CREAT);
if(msgid==-1)
{
fprintf(stderr,"msgget fail error:%d",errno);
exit(1);
}
while(running)
{
if(msgrcv(msgid,(void*)&some_data,BUFSIZ,msg_to_receive,0)==-1)
{
fprintf(stderr,"msgrcv failed with error:%d",errno);
exit(1);
}
printf("You wrote :%s",some_data.some_text);
if(strncmp(some_data.some_text,"end",3)==0)
{
running=0;
}
}
if(msgctl(msgid,IPC_RMID,0)==-1)
fprintf(stderr,"msgctl failed with error\n");
}