SYSTEM-V IPC通信
===============================
1.概念
指的就是:共享内存,消息队列,信号量这三种通信方式
消息队列
===============================
1.原理和特点
允许通信双方选择性的读取信息
如果消息队列中有多条信息的类型是一样,那么接收的时候就按照队列的特点,先发送的先接收
如果消息队列没有你要接收的信息类型,那么msgrcv函数会阻塞
查看消息队列
ipcs -q
删除消息队列
ipcrm -q 消息队列ID
2.相关的接口函数
(1)申请消息队列
#include <sys/msg.h>
int msgget(key_t key, int msgflg);
返回值:成功 返回消息队列的ID
失败 -1
参数:key --》键值
msgflg --》IPC_CREAT
IPC_EXCL
0777
(2)使用消息队列收发信息
发送(写入信息到消息队列):int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
参数:msqid --》消息队列的ID号
msgp --》你要发送的内容
msgsz --》你打算发送多少字节的数据
msgflg --》设置为0
接收(从消息队列中读取信息):ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,int msgflg);
参数:msqid --》消息队列的ID号
msgp --》存放接收的内容
msgsz --》你打算接收多少字节的数据
msgtyp(重点重点重点) --》消息的类型,区分不同的消息
msgflg --》设置为0
依据帮助手册提供信息
struct xxxx
{
long type; //存放消息类型
char buf[100]; //存放真实信息
};
(3)删除/设置/获取消息队列的信息
int msgctl(int msqid, int cmd, struct msqid_ds *buf);
参数:msqid --》消息队列的ID号
cmd --》三个宏定义跟共享内存一样的
buf --》保存消息队列的属性信息
消息队列可以选择性的读消息
#include "myhead.h"
//自定义一个结构体存放要发送的信息
struct msgbuf
{
long type; //消息的类型--》区分不同的消息
char buf[50]; //存放真实的信息
};
int main()
{
int msgid;
//申请消息队列
msgid=msgget(5845,IPC_CREAT|IPC_EXCL|0777);
if(msgid==-1)
{
if(errno==EEXIST)
{
msgid=msgget(5845,0777);
}
else
{
perror("申请消息队列失败!\n");
return -1;
}
}
struct msgbuf msg1;
msg1.type=100;
strcpy(msg1.buf,"hello");
struct msgbuf msg2;
msg2.type=200;
strcpy(msg2.buf,"gec");
struct msgbuf msg3;
msg3.type=300;
strcpy(msg3.buf,"world");
//发送信息给p2
msgsnd(msgid,&msg1,sizeof(msg1),0);
msgsnd(msgid,&msg2,sizeof(msg2),0);
msgsnd(msgid,&msg3,sizeof(msg3),0);
}
#include "myhead.h"
//自定义一个结构体存放要发送的信息
struct msgbuf
{
long type; //消息的类型--》区分不同的消息
char buf[50]; //存放真实的信息
};
int main()
{
int msgid;
//申请消息队列
msgid=msgget(5845,IPC_CREAT|IPC_EXCL|0777);
if(msgid==-1)
{
if(errno==EEXIST)
{
msgid=msgget(5845,0777);
}
else
{
perror("申请消息队列失败!\n");
return -1;
}
}
struct msgbuf msg1;
//接收p1发送过来的信息
msgrcv(msgid,&msg1,sizeof(msg1),300,0);
printf("我收到的内容是:%s\n",msg1.buf);
msgrcv(msgid,&msg1,sizeof(msg1),100,0);
printf("我收到的内容是:%s\n",msg1.buf);
msgrcv(msgid,&msg1,sizeof(msg1),200,0);
printf("我收到的内容是:%s\n",msg1.buf);
}
消息队列中有多条消息类型一致的按照先后顺序读取
#include "myhead.h"
//自定义一个结构体存放要发送的信息
struct msgbuf
{
long type; //消息的类型--》区分不同的消息
char buf[50]; //存放真实的信息
};
int main()
{
int msgid;
//申请消息队列
msgid=msgget(5845,IPC_CREAT|IPC_EXCL|0777);
if(msgid==-1)
{
if(errno==EEXIST)
{
msgid=msgget(5845,0777);
}
else
{
perror("申请消息队列失败!\n");
return -1;
}
}
struct msgbuf msg1;
msg1.type=100;
strcpy(msg1.buf,"hello");
struct msgbuf msg2;
msg2.type=100;
strcpy(msg2.buf,"gec");
struct msgbuf msg3;
msg3.type=100;
strcpy(msg3.buf,"world");
//发送信息给p2
msgsnd(msgid,&msg1,sizeof(msg1),0);
msgsnd(msgid,&msg2,sizeof(msg2),0);
msgsnd(msgid,&msg3,sizeof(msg3),0);
}
#include "myhead.h"
//自定义一个结构体存放要发送的信息
struct msgbuf
{
long type; //消息的类型--》区分不同的消息
char buf[50]; //存放真实的信息
};
int main()
{
int msgid;
//申请消息队列
msgid=msgget(5845,IPC_CREAT|IPC_EXCL|0777);
if(msgid==-1)
{
if(errno==EEXIST)
{
msgid=msgget(5845,0777);
}
else
{
perror("申请消息队列失败!\n");
return -1;
}
}
struct msgbuf msg1;
//接收p1发送过来的信息
msgrcv(msgid,&msg1,sizeof(msg1),100,0);
printf("我收到的内容是:%s\n",msg1.buf);
}