Linux系统编程—消息队列

Linux系统编程—消息队列

1、消息队列相关函数

// 创建和获取 ipc 内核对象
int msgget(key_t key, int flags);
// 将消息发送到消息队列
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
// 从消息队列获取消息
ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);
// 查看、设置、删除 ipc 内核对象(用法和 shmctl 一样)
int msgctl(int msqid, int cmd, struct msqid_ds *buf);

2、消息数据格式

struct Msgbuf {
	long mtype;       /* message type, must be > 0 */
	char mtext[50];    /* message data */
};

3、msgsnd函数
msgsnd 函数用于将数据发送到消息队列。如果该函数被信号打断,会设置 errno 为 EINTR。
使用时需要导入以下头文件:

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>

函数原型:

 int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);

msgid: 由msgget函数返回的消息队列标识码。
msg_ptr:是一个指针,指针指向准备发送的消息。
msg_sz:是msg_ptr指向的消息长度,这个长度不能保存消息类型的那个“long int”长整型计算在内。
msgflg:控制着当前消息队列满或到达系统上限时将要发生的事情。
操作成功,返回“0”,如果失败,则返回“-1”。

4、msgrcv 函数
msgrcv 函数从消息队列取出消息后,并将其从消息队列里删除。
使用时,如果没有包含上面那3个头文件,需包含再使用。
函数原型:

ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);

msgid: 由msgget函数返回的消息队列标识码。
msg_ptr:是一个指针,指针指向准备接收的消息。
msgsz:是msg_ptr指向的消息长度,这个长度不能保存消息类型的那个“long int”长整型计算在内。
msgtype:它可以实现接收优先级的简单形式。
msgflg:控制着队列中没有相应类型的消息可供接收时将要发生的事。
操作成功,返回实际放到接收缓冲区里去的字符个数,如果失败,则返回“-1”。

5、示例
这个程序是向消息队列发消息;

#include<iostream>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include<string.h>
#include<stdio.h>
using namespace std;
struct Msgbuf {
	long mtype;       /* message type, must be > 0 */
	char mtext[50];    /* message data */
};
int main()
{
	int msg_id, msgSendRes;//msgSendRes接收msgsnd的返回值 -1失败  
	struct Msgbuf msgData;//发送消息携带的数据结构体
	bzero(msgData.mtext, sizeof(msgData.mtext));//msgData.mtext内存清0
	msg_id = msgget(key_t(123), IPC_CREAT | 0666);//创建消息队列    失败:-1   成功:返回消息的标识符
	if (msg_id == -1)
	{
		perror("msgget  error");
		return -1;
	}
	//数据准备
	strcpy(msgData.mtext,"hello world");
	msgData.mtype = 1;//发送端mtype设置成多少,接收端对应的mtype也是多少
	msgSendRes = msgsnd(msg_id, &msgData, sizeof(msgData.mtext), 0);//添加消息到消息队列
	//cout << msgData.mtext << endl;
	if (msgSendRes == -1)
	{
		perror("msgsnd  error");
		return -1;
	}
	return 0;
}

在Linux环境下,输入命令ipcs,查看消息队列:
在这里插入图片描述
此时说明,我们的消息已经写入消息队列中,等待读取。

接收消息代码:

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

using namespace std;

struct Msgbuf {
	long mtype;       /* message type, must be > 0 */
	char mtext[50];    /* message data */
};

int main()
{
	int msg_id;//接收msgget的返回值 
	ssize_t msgrcvRes;//接收msgrcv函数的返回值 -1 失败
	struct Msgbuf msgData;//数据结构体
	bzero(msgData.mtext, sizeof(msgData.mtext));//msgData.mtext清0
	msg_id = msgget(key_t(123), IPC_CREAT | 0666);//创建消息队列  成功:返回消息标识符 失败:-1
	if (msg_id == -1)
	{
		perror("msgget error");
		return -1;
	}
	msgrcvRes = msgrcv(msg_id, &msgData, sizeof(msgData.mtext), 1, 0);//从消息队列里检索消息
	if(msgrcvRes==-1)
	{
		perror("msgrcv error");
		return -1;
	}
	cout << "检索到的消息为:" << msgData.mtext << endl;
	return 0;
}

运行此程序:
在这里插入图片描述
可以看到已经检索到消息队列里面的消息;再次输入命令ipcs,可以发现消息队列里面的消息数已经减一。
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值