消息队列:是消息的链接表,可以把消息看作一个记录,具有特定
的格式以及特定的优先级。
对消息队列有写权限的进程可以向其中按照一定的规则添加新消息;
对消息队列有读权限的进程则可以从消息队列中读走消息。
msgget用于创建或打开一个队列;msgsnd用于将新消息添加到队列尾端;msgrcv用于从队列中获取消息。并不一定要以先进先出的顺序取消息,也可以按消息的类型取消息。
每个消息队列都有一个msqid_ds结构与其关联,此结构体保存着消息队列当前的状态信息。
1.函数msgget
#include<sys/msg.h>
int msgget(key_t key,int flag);
返回值:成功返回消息队列ID,出错返回-1
参数key:消息队列关联的标识符;
参数flag:消息队列的建立标志和存取权限。IPC_CREAT 如果内核
中没有此队列则创建它;IPC_EXCL 当和IPC_CREAT 一起使用时,如果
队列已经存在,则失败。
2.函数msgctl
#include<sys/msg.h>
int msgctl(int msqid,int cmd,struct msqid_ds *buf);
返回值:成功返回0;出错返回-1
函数msgctl对队列执行多种操作,
参数cmd指定对队列要执行的命令:
IPC_STAT :取队列的msqid_ds结构,并将它放在buf指向的结构中;
IPC_SET :将字段msg_perm.uid ,msg_perm.gid,msg_perm.mod和msg_perm.qbytes。从buf指向的结构复制到与这个队列相关的msqids_ds结构中。
IPC_RMID::从系统中删除该消息队列。
3.函数msgsnd
#include<sys/msg.h>
int msgsnd(int msqid,const void *ptr,size_t nybtes,int flags);
返回值:成功返回0;出错返回-1
参数msqid:消息队列的标识码;
参数*ptr:指向消息缓冲区的指针,此位置用来暂时存储发送和接收
的消息,是一个用户可定义的通用结构;
struct msgbuf
{
long int mtype;
char mtext[512];
}
参数nybtes:消息的长短
参数msgflg:标志位
4.函数msgrcv
#include<sys/msg.h>
ssize_t msgrcv(int msqid,void *ptr,size_t nybtes,long type,int flag);
返回值:成功返回消息数据部分长度,失败返回-1
参数msqid:消息队列的标识码;
参数*ptr:指向消息缓冲区的指针,此位置用来暂时存储发送和接收
的消息,是一个用户可定义的通用结构;
参数nbytes:消息的长短
参数flags:标志位
参数type:可以指定想要哪一种信息
type==0 返回队列中第一个信息
type>0 返回队列消息中类型为type的第一个消息
type<0 返回队列中消息类型小于等于type绝对值的消息,如果这种消息有若干个,则取类型值最小的消息。
例程写消息队列
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include <sys/msg.h>
#include <errno.h>
struct msgbuf //指向消息缓冲区的指针,此位置用来暂时存储发送和接收的消息,自定义
{
long int mtype;
char mtext[512];
}
int main()
{
int runing=1;
struct msgbuf data;
char buffer[BUFSIZ]; //BUFSIZ是一个常量
int msgid=-1;
if((msgid=msgget((key_t 1234),0666|IPC_CREAT))==-1){ //获得一个消息队列,不存在就创建它
fprintf(stderr,"err %d\n",errno);
exit(1);
}
while(runing)
{
printf("plesse enter some characters:\n ");
fgets(buffer,BUFSIZ,stdin); //从标准输入流,写入数据到buffer中
data.mtype=1;
stpcpy(data.mtext,buffer); //把数据复制到缓存区
if(msgsnd(msgid,void(*)&data,512,0)==-1){ //将数据写到消息队列
fprintf(stderr,"msgsnd err");
exit(1);
}
if(strncmp(buffer,"end",3)==0) //当输入end时,表示输入结束
runing=0;
sleep(1);
}
exit(0);
}
例程读消息队列
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/msg.h>
#include <errno.h>
struct msgbuf //指向消息缓冲区的指针,此位置用来暂时存储发送和接收的消息,自定义
{
long int mtype;
char mtext[512];
}
int main()
{
int running = 1;
struct msg_st data;
char buffer[BUFSIZ];
int msgid = -1;
if((msgid=msgget((key_t 1234),0666|IPC_CREAT))==-1){ //获得一个消息队列,不存在就创建它
fprintf(stderr,"err %d\n",errno);
exit(1);
}
while(runing)
{
if(msgrcv(msgid, (void*)&data, 512,0, 0) == -1)
{
fprintf(stderr, "msgsnd failed\n");
exit(1);
}
if(strncmp(data.mtext, "end", 3) == 0)
running = 0;
}
if(msgctl(msgid, IPC_RMID, 0) == -1) //,该函数执行多种操作,IPC_RMID表示删除消息队列
{
fprintf(stderr, "msgctl(IPC_RMID) failed\n");
exit(1);
}
exit(0);
}