Linux下进程间通信之消息队列

    消息队列是进程间通信之一,当然还有其他通信方式:管道,有名管道,内存共享,套接字等,下面详细介绍消息队列的用法。

首先介绍几个函数

int msgctl(int msgid , ing cmd , struct msgid_ds *buf);

int msgget(key_t key , ingt msgflg);

int msgrcv(ing msgid , void* msg_ptr , size_t msg_sz , long int msgtype , int msgflg);

int msgsnd(int msgid , const void* msg_ptr , size_t msg_sz , int msgflg);

这些函数的作用跟共享内存和信号量的作用是相同的。

int msgctl(int msgid , ing cmd , struct msgid_ds *buf);: 控制函数,用来控制消息列队的关闭等。

int msgget(key_t key , ingt msgflg);用来创建一个消息列队

int msgrcv(ing msgid , void* msg_ptr , size_t msg_sz , long int msgtype , int msgflg);用来接收一个消息

int msgsnd(int msgid , const void* msg_ptr , size_t msg_sz , int msgflg);用来发送一个消息


下面来看一个具体的例子。在这个例子中,我们将在客户端中对消息进行接收,在接收完所有的消息后,删除消息列队。

在服务器中,我们将发送消息到消息列队中,直到遇到end结束符为止。

发送消息源程序,命名为msgsend.c

#include<stdlib.h>  
#include<stdio.h>  
#include<string.h>  
#include<errno.h>  
#include<unistd.h>  
#include<sys/msg.h>  

#define BUFSIZE 1024

struct msg_st
{
	int msg_type;
	char msg_buf[BUFSIZE];
};

int main(int argc, char *argv[])
{
	int msgid;//定义消息队列id
	key_t key;//唯一识别两通信的消息队列,要与接收方一致
	struct msg_st msg_data;
	char buffer[BUFSIZE];
	int runnig = 1;

	//消息队列是否创建成功
	if((msgid = msgget(key = 1234, 0666 | IPC_CREAT)) == -1)
	{
		fprintf(stderr, "msgget failed with error:%d\n",errno);
		exit(-1);	
	}


	while(runnig)
	{
		//get some data
		printf("enter some data:");
		fgets(buffer,BUFSIZE,stdin);
		msg_data.msg_type = 1;
		strcpy(msg_data.msg_buf,buffer);
		
		//send data
		if(msgsnd(msgid, (void *)&msg_data, BUFSIZE, 0) == -1)
		{
			fprintf(stderr, "msgsend failed with error:%d\n",errno);
			exit(-1);
		}

		//exit with end
		if(strncmp(msg_data.msg_buf,"end",3) == 0)
		{
			runnig = 0;
		}
		
	}

	if(msgctl(msgid,IPC_RMID,0) == -1)
	{
		fprintf(stderr, "msgctl failed with error:%d\n",errno);
		exit(-1);
	}
	
	exit(0);
	
}


接收消息源程序,命名为 msgrcv.c

#include<stdlib.h>  
#include<stdio.h>  
#include<string.h>  
#include<errno.h>  
#include<unistd.h>  
#include<sys/msg.h>  

#define BUFSIZE 1024

struct msg_st
{
	int msg_type;
	char msg_buf[BUFSIZE];
};

int main(int argc, char *argv[])
{
	int msgid;
	key_t key;
	struct msg_st msg_data;
	int msg_recv = 0;
	int runnig = 1;

	if((msgid = msgget(key = 1234, 0666 | IPC_CREAT)) == -1)
	{
		fprintf(stderr, "msgget failed with error:%d\n",errno);
		exit(-1);	
	}


	while(runnig)
	{
		if(msgrcv(msgid, (void *)&msg_data, BUFSIZE, msg_recv, 0) == -1)
		{
			fprintf(stderr, "msgrcv failed with error:%d\n",errno);
			exit(-1);
		}

		//以end结束
		printf("receive data: %s\n",msg_data.msg_buf);
		if(strncmp(msg_data.msg_buf,"end",3) == 0)
		{
			runnig = 0;
		}
		
	}
	
	//关闭消息队列
	if(msgctl(msgid,IPC_RMID,0) == -1)
	{
		fprintf(stderr, "msgctl failed with error:%d\n",errno);
		exit(-1);
	}
	exit(0);
}


消息队列的用法比较简单,大概分为以下几步:

1.定义一个结构体用来存放数据,msg_data和msg_type

2.定义消息队列id,创建消息队列 msgget(){}

3.消息队列接收和发送函数 msgrcv(){}和 msgsnd(){}

4.关闭消息队列 msgctl(){}

注意:在定义key_t key 的时候,发送和接收的key值要相同



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值