linux系统编程-进程间通信-消息队列

该博客介绍了如何在Linux中使用消息队列进行进程间通信。内容包括创建和打开消息队列、发送与接收消息的函数msgget、msgsnd、msgrcv的使用,以及删除消息队列的方法msgctl。示例代码展示了父子进程如何分别进行发送和接收消息。
摘要由CSDN通过智能技术生成

操作步骤:

1.创建/打开消息队列

相关函数:

int  msgget(key_t  键值,int  打开方式)

参数:键值 – 通过ftok()获取

打开方式:IPC_CREAT/0666

成功是凡是msgid  失败是返回-1

2.收消息/发消息

发送消息:

int  msgsnd(int msgid,const void *msgp,size_t size,int flag)

int  msgrecv(int msgid,const void *msgp,size_t size,int flag)

 

参数1: msgget 的返回值

size 消息的长度

flag: 0 表示没有数据时候会阻塞

msgp:需要自定义一个消息结构体,定义一个数据域和一个数据类型域的数据域。

返回值:收消息或者发消息的字节数。

 

注意,如果接收消息失败,并且原因是:检查接收消息的长度是不是比发送消息的长度小。

3.删除消息队列

删除消息队列:

int msgctl(int  消息队列的ID, int  IPC_RMID,NULL)

 

消息队列和共享内存区别:

共享内存中的数据在读取之后还存在,

消息队列会在数据读取之后会消失。取消息:方式1:按照标记读取数据,方式2:按照顺序读取数据

 

创建或打开消息队列 msgget

添加消息 msgsnd

读取消息 msgrcv    可以按照类型吧消息从消息队列中取出

控制消息队列 msgctl   读取消息队列属性,并保存到buf指向缓冲区, 设置消息队列属性。从消     息中删除消息队列

消息队列发送

#include <stdio.h>
#include <sys/types.h>
#include <sys/msg.h>
#include <string.h>
#include <sys/ipc.h>
#include <unistd.h>

#define SIZE 100


typedef struct msgBuf
{
	long msgType;
	char msgContent[SIZE];
}MSG;

int main(int argv,const char *argc[])
{
	key_t keyRead = 0;
	key_t keyWrite = 0;
	int msgWriteID = 0;
	int msgReadID = 0;
	pid_t pid;
	MSG msg;
	int ret = 0;
	
	//创建新的进程
	pid = fork();
	if(pid < 0)
	{
		perror("fork fail:");
		return -1;
	}

	//创建并且打开消息队列-发送
	keyWrite = ftok("/tmp", 11);
	printf( "key=0x%x\r\n", keyWrite );
	
	msgWriteID = msgget( keyWrite, IPC_CREAT | 0666 );
	if ( msgWriteID < 0 )
	{
		perror("msg get error");
		return -1;
	}
	printf("msgWriteID = %d\r\n", msgWriteID);
	
	//创建消息队列 - 读操作
	keyRead = ftok("/tmp",12);
	printf("keyRead = %x\r\n",keyRead);

	msgReadID = msgget(keyRead,IPC_CREAT|0666);
	if(msgReadID < 0)
	{
		perror("msgReadID fail:");
		return -1;
	}
	

	if(pid > 0)//父进程负责收消息
	{		
		memset( &msg, 0, sizeof(msg) );
		msg.msgType = 3;
		strncpy( msg.msgContent , "AAAAAA", SIZE - 1 );
		ret = msgsnd( msgWriteID, &msg, SIZE, 0);
		if (ret < 0)
		{
			perror("msg snd error");
		}
	}else if(pid == 0)//子进程负责发送消息
	{
		//创建新的消息队列 - 发消息
		memset( &msg, 0, sizeof(msg) );
		gets(msg.msgContent);
		msg.msgType = 3;
		//strncpy( msg.msgContent , "AAAAAA", SIZE - 1 );
		ret = msgsnd( msgWriteID, &msg, SIZE-20, 0);
		if (ret < 0)
		{
			perror("msg snd error");
		}
	}

	//删除消息队列
	msgctl(msgReadID,IPC_RMID,NULL);
	return 0;
}

消息队列接收

#include <stdio.h>
#include <sys/types.h>
#include <sys/msg.h>
#include <string.h>
#include <sys/ipc.h>
#include <unistd.h>

#define SIZE 100

typedef struct msgBuf
{
	long msgType;
	char msgContent[SIZE];
}MSG;

int main(int argv,const char *argc[])
{
	key_t keyRead = 0;
	key_t keyWrite = 0;
	int msgReadID = 0;
	int msgWriteID = 0;
    pid_t pid;	
	MSG msg;
	int ret=0;	

	//创建新的进程
	pid = fork();
	if(pid < 0)
	{
		perror("fork Fail: ");
		return -1;
	}


	//创建并且打开消息队列-读操作
	keyRead = ftok("/tmp", 11);
	printf( "keyRead = 0x%x\r\n", keyRead );
	
	msgReadID = msgget( keyRead, IPC_CREAT | 0666 );
	if ( msgReadID < 0 )
	{
		perror("msgReadID error");
		return -1;
	}		
	
	//创建并且打开新的队列消息-发送
	keyWrite = ftok("/tmp",12);
	printf("keyWrite = %x\r\n",keyWrite);

	msgWriteID = msgget(keyWrite,IPC_CREAT|0666);
    if(msgWriteID < 0)
	{
		perror("msgWriteID Fail: ");
		return -1;
	}


	if(pid > 0)//父进程负责发消息
	{
		memset(&msg,0,sizeof(msg));
		gets(msg.msgContent);
		msg.msgType = 3;
		ret = msgsnd(msgWriteID,&msg,SIZE-20,0);
		if(ret < 0)
		{
			perror("msgsnd Fail:");
		}
			
	}else if(pid == 0)//子进程负责收消息
	{	
		//收消息
		memset(&msg, 0, sizeof(msg));
		msg.msgType = 3;
		if (0 >  msgrcv(msgReadID, &msg, SIZE,  msg.msgType ,  0))
		{
			perror( "msg rcv error" );
		}
		else 
		{		
			printf("msg:%s\r\n", msg.msgContent);
		}
	}



	//删除消息队列
	msgctl ( msgReadID, IPC_RMID, NULL );
	return 0;
}

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值