system v 消息队列(二)

本文详细介绍了使用msgsnd和msgrcv函数进行消息队列通信的方法。包括如何发送和接收消息,以及各种参数的具体含义。并通过示例代码展示了具体的应用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.msgsnd函数

(1)功能:把一条消息添加到消息队列中

(2)原型:intmsgsnd(int msqid, const void* msgp. size_t msgsz, int msgflg);

(3)参数:msgqid:由msgget函数返回的消息队列标识码

                       msgp:是一个指针,指针指向准备发送的消息

                       msgsz:是msgp指向的消息长度,这个长度不含保存消息类型的那个long int长整型

                       msgflg:控制着当前消息队列满或到达系统上限时将要发生的事情

(4)返回值:成功返回0,;失败返回-1

(5)msgflg=IPC_NOWAIT表示队列满不等待,返回EAGAIN错误

(6)消息结构在两方面收到制约。首先它必须小于系统规定的上限值;其次,它必须以一个long int长整数开始,接收者函数将利用这个长整数确定消息的类型

(7)消息结构参考形式如下:

           struct msgbuf {

                   long mtype;

                   char mtext[1];

           };

2.msgrcv函数

(1)功能:是从一个消息队列接收消息

(2)原型:ssize_t msgrcv(int msgqid, void*msgp, size_t msgsz, long msgtyp, int msgflg);

(3)参数:msgid:由msgget函数返回的消息队列标识码

                       msgp:是一个指针,指针指向准备接收的消息

                        msgsz:是msgp指向的消息长度,这个长度不含保存消息类型的那个long int长整型

                        msgtype:它可以实现接收优先级的简单形式

                        msgflg:控制着队列中没有相应类型的消息可供接收时将要发生的事

(4)返回值:成功返回实际放到接收缓冲区里去的字符个数,失败返回-1

(5)msgtype=0返回队列第一条消息

(6)msgtyp>0返回队列第一条类型等于msgtype的消息

(7)msgtyp<0返回队列第一条类型小于等于msgtype绝对值的消息(消息类型最小的先接收)

(8)msgflg=IPC_NOWAIT,队列没有可读消息不等待,返回ENOMSG错误

(9)msgtyp=MSG_NOERROR,消息大小超过msgsz是被截断

(10)msgtyp>0且msgflg=MSG_EXCEPT,接收类型不等于msgtype的第一条消息

3.示例

msg_send.cpp

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

#include <stdlib.h>
#include <stdio.h>
#include <errno.h>


#define ERR_EXIT(m) \
    do \
    { \
    	perror(m); \
    	exit(EXIT_FAILURE); \
    }while(0)

struct MSG {
	long mtype;
	char mtext[1];
};

int main(int argc, char* argv[]) {
	if(argc != 3) {
		fprintf(stderr, "Usage: %s <bytes> <type>\n", argv[0]);
		exit(EXIT_FAILURE);
	}
	
	int len = atoi(argv[1]);
	int type = atoi(argv[2]);
	int msgid;
	msgid = msgget(1234, 0); //按照原来创造的权限打开
	if(msgid == -1) 
		ERR_EXIT("msgget");
	
	struct MSG* ptr;
	ptr = (struct MSG*)malloc(sizeof(long)+len);
	ptr->mtype = type;
	if(msgsnd(msgid, ptr, len, 0) <0)
		ERR_EXIT("msgsnd");
	return 0;
}

msg_recv.cpp

./recv -n -t 2

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

#include <stdlib.h>
#include <stdio.h>
#include <errno.h>


#define ERR_EXIT(m) \
    do \
    { \
    	perror(m); \
    	exit(EXIT_FAILURE); \
    }while(0)

struct MSG {
	long mtype;
	char mtext[1];
};

#define MSGMAX 8192

int main(int argc, char* argv[]) {
	
	int flag = 0;
	int type = 0;
	int opt;
	
	while(1) {
		opt = getopt(argc, argv, "nt:");
		if(opt == '?')
			exit(EXIT_FAILURE);
		if(-1 == opt)
			break;
		
		switch(opt) {
		case 'n':
			flag |= IPC_NOWAIT;
			break;
		case 't':
			//int n = atoi(optarg);
			//printf("n=%d\n", n);
			type = atoi(optarg);
			break;
		}
	}
	int msgid;
	msgid = msgget(1234, 0); //按照原来创造的权限打开
	if(msgid == -1) 
		ERR_EXIT("msgget");
	
	struct MSG* ptr;
	ptr = (struct MSG*)malloc(sizeof(long)+MSGMAX);
	ptr->mtype = type;
	int n = 0;
	if((n=msgrcv(msgid, ptr, MSGMAX, type, flag)) < 0)
		ERR_EXIT("msgsnd");
	printf("read %d bytes type=%ld\n", n, ptr->mtype);
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值