消息队列

消息队列:
基本特点:是由内核负责维护管理的数据链表,通过消息类型收发数据。

int msgget(key_t key, int msgflg);
功能:创建/获取消息队列
key:IPC键值
msgflg:
IPC_CREAT 创建消息队列
IPC_EXCL 如果消息队列已经存在则返回错误
mode_flags:创建消息队列时需要提供权限
返回值:成功返回IPC标识符,错误返回-1。

int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
功能:向消息队列发送数据
msqid:IPC标识符
msgp:要发送的消息的首地址
struct msgbuf {
long mtype; // 消息类型
char mtext[5]; // 数据
};
msgsz:数据的字节数,不包含消息类型。
msgflg:
阻塞一般写0。
IPC_NOWAIT 当消息队列满时,不等待立即返回。

ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,
int msgflg);
功能:从消息队列中读取数据
msqid:IPC标识符
msgp:存储数据结构首地址
msgsz:结构体的字节数
msgtyp:消息类型
>0 读取消息类型等于msgtyp的消息。
=0 读取消息队列第一条消息。
<0 读取消息类型小于abs(msgtyp)的消息,如果有多个则读取最小的。
msgflg:
IPC_NOWAIT 消息类型不符合时不阻塞,立即返回。
MSG_EXCEPT 如果msgtyp>0,则读取第一个消息类型不是msgtyp的消息。
MSG_NOERROR 如果不包含些标志,消息实际长度>msgsz,则返回错误不读取数据,若包含此标志,则读取msgsz个字节。
返回值:成功读取到的字节数

int msgctl(int msqid, int cmd, struct msqid_ds *buf);
功能:删除/获取消息的属性
msqid:IPC标识符
cmd:
IPC_STAT 获取消息队列的属性
IPC_SET 设置消息队列的属性
IPC_RMID 删除消息队列
buf:
struct msqid_ds {
struct ipc_perm msg_perm; 属主信息
time_t msg_stime; 最后发送时间
time_t msg_rtime; 最后接收时间
time_t msg_ctime; 最后修改时间
unsigned long __msg_cbytes; 当前消息队列字节数
msgqnum_t msg_qnum; 当前消息的数量
msglen_t msg_qbytes; 一条消息的最大字节数
pid_t msg_lspid; 最后发送者PID
pid_t msg_lrpid; 最后接收者PID
};

编程模型:
    进程A           进程B
    创建消息队列    获取消息队列
    发送消息        接收消息
    接收消息        发送消息
    删除消息队列
在这里插入代码片
```#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include "message.h"

int main(int argc,const char* argv[])
{
	// 创建消息队列
	int msgid = msgget(ftok(".",120),IPC_CREAT|0644);
	if(0 > msgid)
	{
		perror("msgget");
		return -1;
	}

	Msg msg = {};
	for(;;)
	{
		msg.type = 5;
		printf(">>>");
		gets(msg.data);
		// 发送消息
		if(msgsnd(msgid,&msg,strlen(msg.data)+1,0))
		{
			perror("msgsne");
			break;
		}
		if(0 == strcmp(msg.data,"quit")) break;

		// 接收消息
		if(0 == msgrcv(msgid,&msg,MSGMAX,6,0))
		{
			perror("msgrcv");
			break;
		}
		printf("recv:%s\n",msg.data);
		if(0 == strcmp(msg.data,"quit")) break;
	}
	printf("通信结束!\n");

	usleep(1000);

	// 删除消息队列
	if(msgctl(msgid,IPC_RMID,NULL))
	{
		perror("msgctl");
		return -1;
	}
	
	return 0;



```c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include "message.h"

int main(int argc,const char* argv[])
{
	// 创建消息队列
	int msgid = msgget(ftok(".",120),IPC_CREAT|0644);
	if(0 > msgid)
	{
		perror("msgget");
		return -1;
	}

	Msg msg = {};
	for(;;)
	{
		// 接收消息
		if(0 == msgrcv(msgid,&msg,MSGMAX,5,0))
		{
			perror("msgrcv");
			break;
		}
		printf("recv:%s\n",msg.data);
		if(0 == strcmp(msg.data,"quit")) break;

		msg.type = 6;
		printf(">>>");
		gets(msg.data);
		// 发送消息
		if(msgsnd(msgid,&msg,strlen(msg.data)+1,0))
		{
			perror("msgsne");
			break;
		}
		if(0 == strcmp(msg.data,"quit")) break;
	}
	printf("通信结束!\n");

	return 0;
}


  • 6
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值