消息队列是由消息的链表,存放在内核中并由消息队列标识符标识。消息队列克服了信号传递信息少、管道只能承载无格式字节流以及缓冲区大小受限等缺点。
#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include<sys/msg.h>
int main(void)
{
//合成键
printf("%d进程:合成键\n",getpid());
key_t key = ftok(".",123);
if(key == -1)
{
perror("ftok");
return -1;
}
//创建消息队列
printf("%d进程:创建消息队列\n",getpid());
int msg_id = msgget(key,IPC_CREAT | IPC_EXCL | 0664);
if(msg_id == -1)
{
perror("msgget");
return -1;
}
//写入消息队列
printf("%d进程:写入消息队列\n",getpid());
while(1)
{
//通过键盘获取数据
struct
{
long type;//消息类型
char data[128];//数据
}msgbuf = {1234,""};
fgets(msgbuf.data,sizeof(msgbuf.data),stdin);
if(strcmp(msgbuf.data,"!\n") == 0)
{
break;
}
//把获取的数据做为节点插入队列中
if(msgsnd(msg_id,&msgbuf,strlen(msgbuf.data),0) == -1)
{
perror("msgsnd");
return -1;
}
}
//销毁消息队列
printf("%d进程:销毁消息队列\n",getpid());
if(msgctl(msg_id,IPC_RMID,NULL) == -1)
{
perror("msgctl");
return -1;
}
return 0;
}
#include<stdio.h>
#include<unistd.h>
#include<sys/msg.h>
#include<errno.h>
int main(void)
{
//合成键
printf("%d进程:合成键\n",getpid());
key_t key = ftok(".",123);
if(key == -1)
{
perror("ftok");
return -1;
}
//获取消息队列
printf("%d进程:获取消息队列\n",getpid());
int msg_id = msgget(key,0);
if(msg_id == -1)
{
perror("msgget");
return -1;
}
//接收数据
printf("%d进程:接收数据\n",getpid());
while(1)
{
struct
{
long type;//数据类型
char data[128];
}msgbuf = {};
ssize_t size = msgrcv(msg_id,&msgbuf,sizeof(msgbuf.data)-sizeof(msgbuf.data[0]),1234,0);
if(size == -1)
{
if(errno == EIDRM)
{
break;
}
perror("msgrcv");
return -1;
}
printf("%ld,%s",msgbuf.type,msgbuf.data);
}
return 0;
}