Linux下进程间通讯-消息队列

文章介绍了SYSTEM-VIPC中的消息队列通信机制,包括其允许通信双方选择性读取信息的原理和特点,以及消息队列的创建、使用、删除的相关函数如msgget、msgsnd、msgrcv和msgctl。示例代码展示了如何发送和接收不同类型的消息。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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);
	

	

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hqb_newfarmer

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值