消息队列在内核中开辟
为半双工
消息的类型就是结构体,这个需要我们自己定义(叫啥名都无所谓)
第一个成员必须为 long type,剩下的都无所谓。
- 发送消息时,消息类型 >0
- 接收消息时,消息类型可以置为0,表示不区分消息类型
- 如果读取时,队列中没有读消息时设定的类型,则它会一直阻塞在那里
struct mess
{
long type;
char buff[32];//格式由我们自己定义
};
API
int msgget(key_t key, int msqflg);创建或者获取一个消息队列
成功返回消息队列ID,失败返回-1
msqflg:IPC_CREAT
int msgsnd(int msqid, const void *msqp, size_t msqsz, int msqflg);发送一条消息
成功返回0,失败返回-1
msqsz:指定mtext中有效数据的长度
msqflg:一般设置为0可以设置IPC_NOWAIT
ssize_t msgrcv(int msqid, void *msgp, size_t msqsz, long msqtyp, int msqflg); 接收一条消息
成功返回mtext中接收到的数据长度,失败返回-1
msqtyp:指定接收的消息类型,类型可以为0
msqflg:一般设置为О可以设置IPC_NOWAIT
int msgctl(int msqid, int cmd, struct msqid_ds *buf); 控制消息队列
成功返回0,失败返回-1
cmd: IPC_RMID
案例: 两个进程往消息队列发送消息不同类型的消息,然后接收对方发送的消息
messagequeue1.cpp
#include<iostream>
#include<unistd.h>
#include<sys/msg.h>
#include<cstring>
struct mess
{
long type;
char buff[32];
};
int main()
{
int msgid = msgget((key_t)1234,IPC_CREAT|0600);
if(msgid == -1)
{
std::cout<<"msgget erro"<<std::endl;
exit(1);
}
struct mess ms1;
msgrcv(msgid,&ms1,32,1,0);
std::cout<<ms1.buff<<std::endl;
memset(&ms1,0,sizeof(ms1));
ms1.type=2;
strcpy(ms1.buff,"hello2");
msgsnd(msgid,&ms1,32,0);
exit(1);
}
messagequeue2.cpp
#include<iostream>
#include<unistd.h>
#include<sys/msg.h>
#include<cstring>
struct mess
{
long type;
char buff[32];
};
int main()
{
int msgid = msgget((key_t)1234,IPC_CREAT|0600);
if(msgid == -1)
{
std::cout<<"msgget erro"<<std::endl;
exit(1);
}
struct mess ms1;
ms1.type=1;
strcpy(ms1.buff,"hello1");
msgsnd(msgid,&ms1,32,0);
memset(&ms1,0,sizeof(ms1));
msgrcv(msgid,&ms1,32,2,0);
std::cout<<ms1.buff<<std::endl;
exit(0);
}
运行结果
ipcs -q 查看消息队列