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

 1、认识消息队列      

       消息队列就是一个消息的链表,存放于内核中。可以把消息看作一个记录,具有特定的格式以及特定的优先级,一个消息队列由一个标识符(即队列ID)来标识。具有写权限的进程可以往消息队列中添加新消息,具有读权限的进程可以从消息队列中读取消息。 

2、特点

(1)消息队列是面向记录的,其中的消息具有特定的格式以及特定的优先级

(2)消息队列独立于发送与接收进程。进程终止时,消息队列及其内容并不会被删除。

(3)消息队列可以实现消息的随机查询,消息不一定要以先进先出的次序读取,也可以按消息的类型读取。

3、函数原型

#include <sys/msg.h>
int msgget(key_t key, int flag);// 创建或打开消息队列:成功返回队列ID,失败返回-1

int msgsnd(int msqid, const void *ptr, size_t size, int flag);// 添加消息到消息队列:成功返回0,失败返回-1

int msgrcv(int msqid, void *ptr, size_t size, long type,int flag);// 从消息队列读取消息:成功返回消息数据的长度,失败返回-1

int msgctl(int msqid, int cmd, struct msqid_ds *buf);// 控制消息队列:成功返回0,失败返回-1

在以下两种情况下,msgget将创建一个新的消息队列:

  1. 如果没有与键值key相对应的消息队列,并且flag中包含了IPC_CREAT标志位。
  2. key参数为IPC_PRIVATE。

函数msgrcv在读取消息队列时,type参数有下面几种情况:

  1. type == 0,返回队列中的第一个消息;
  2. type > 0,返回队列中消息类型为 type 的第一个消息;
  3. type < 0,返回队列中消息类型值小于或等于 type 绝对值的消息,如果有多个,则取类型值最小的消息。

4、代码演示

      我们在这里创建两个程序,一个用来接收消息,一个用来发送消息。这里根据正常的情况,我们允许两个程序都可以创建消息,但只有接收者在接收完最后一个消息之后,它才把它删除。

msgrecv.c源代码:

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <sys/msg.h>
 
struct msg_st
{
	long int msg_type;
	char text[BUFSIZ];
};
 
int main()
{
	int running = 1;
	int msgid = -1;
	struct msg_st data;
	long int msgtype = 0; //注意1
 
	//建立消息队列
	msgid = msgget((key_t)1234, 0666 | IPC_CREAT);
	if(msgid == -1)
	{
		fprintf(stderr, "msgget failed with error: %d\n", errno);
		exit(EXIT_FAILURE);
	}
	//从队列中获取消息,直到遇到end消息为止
	while(running)
	{
		if(msgrcv(msgid, (void*)&data, BUFSIZ, msgtype, 0) == -1)
		{
			fprintf(stderr, "msgrcv failed with errno: %d\n", errno);
			exit(EXIT_FAILURE);
		}
		printf("You write: %s\n",data.text);
		//遇到end结束
		if(strncmp(data.text, "end", 3) == 0)
			running = 0;
	}
	//删除消息队列
	if(msgctl(msgid, IPC_RMID, 0) == -1)
	{
		fprintf(stderr, "msgctl(IPC_RMID) failed\n");
		exit(EXIT_FAILURE);
	}
	exit(EXIT_SUCCESS);
}

msgsend.c源代码:

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/msg.h>
#include <errno.h>
 
#define MAX_TEXT 512
struct msg_st
{
	long int msg_type;
	char text[MAX_TEXT];
};
 
int main()
{
	int running = 1;
	struct msg_st data;
	char buffer[BUFSIZ];
	int msgid = -1;
 
	//建立消息队列
	msgid = msgget((key_t)1234, 0666 | IPC_CREAT);
	if(msgid == -1)
	{
		fprintf(stderr, "msgget failed with error: %d\n", errno);
		exit(EXIT_FAILURE);
	}
 
	//向消息队列中写消息,直到写入end
	while(running)
	{
		//输入数据
		printf("Please input: ");
		fgets(buffer, BUFSIZ, stdin);
		data.msg_type = 1;    //注意2
		strcpy(data.text, buffer);
		//向队列发送数据
		if(msgsnd(msgid, (void*)&data, MAX_TEXT, 0) == -1)
		{
			fprintf(stderr, "msgsnd failed\n");
			exit(EXIT_FAILURE);
		}
		//输入end结束输入
		if(strncmp(buffer, "end", 3) == 0)
			running = 0;
		sleep(1);
	}
	exit(EXIT_SUCCESS);
}

运行结果如下:


 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值