POSIX消息队列 发送接收简单子

Linux的函数库提供有两种消息队列,一种是POSIX消息队列,另一种是SYS V消息队列。这里介绍POSIX消息队列。

涉及到的函数主要有:

  • mq_open() - 创建消息队列
  • mq_close() - 关闭消息队列
  • mq_send() - 往消息队列里发送消息
  • mq_receive() - 从消息队列里接受消息
消息队列实际上是一个文件,因此需要消息队列虚拟文件系统的支持。通常系统启动时,在/dev目录下,会有一个/mqueue目录来暂存所有的消息队列。如果没有这个目录,就需要先挂载。
# mkdir /dev/mqueue
# mount -t mqueue none /dev/mqueue

打开和关闭消息队列的操作和打开关闭普通文件的操作几乎一样。而发送接收也和普通文件的读写操作十分相似。
mqd_t mq_open(const char *name, int oflag);
mqd_t mq_open(const char *name, int oflag, mode_t mode,
                     struct mq_attr *attr);
打开操作有两个形式,通常使用第二种形式的打开函数。因为它有更多的可选参数,可以控制文件的打开方式和读写权限。参数中,name是文件的 路径 ,根据mq_overview的man page所说,它的形式必须是/somename(以斜线开头),这里的somename也是最终在/dev/mqueue中可以看见的消息队列的文件名。第二个参数oflag是打开方式,只读、只写、读写等方式,与open的参数相同。第三个是mode是文件的权限(755、777等),也是和open相同的。最后一个参数attr是消息队列的参数。执行成功,返回已打开的消息队列的描述符。

int mq_send(mqd_t mqdes, const char *msg_ptr,
                     size_t msg_len, unsigned msg_prio);
mq_send()用于写一条消息到消息队列。第一个参数mqdes是消息队列的描述符,也就是mq_open()函数的返回值。第二个msg_ptr是要发送的消息的指针。第三个msg_len是要发送的消息的长度。第四个msg_prio是消息的优先级,优先级按降序排列,数字越大优先级越高。

ssize_t mq_receive(mqd_t mqdes, char *msg_ptr,
                          size_t msg_len, unsigned *msg_prio);
mq_receive()用于从消息队列读取一条消息。第一个参数mqdes是消息队列的描述符。第二个msg_ptr是接收消息的缓冲区。第三个msg_len是要接收的消息的长度。第四个msg_prio是消息的优先级。

发送端:
/× server.c */
#include <stdio.h>

#include <fcntl.h>           /* For O_* constants */
#include <sys/stat.h>        /* For mode constants */
#include <mqueue.h>

#include <string.h>
#include <errno.h>

#define PATHNAME "/msg_test"
#define PRIOLOW 1
#define PRIOHIGH 2

int main()
{
	mqd_t mqd;
	char name[24] = "/msg_test";
	char data[24] = "Hello World!";
	char data_new[32] = "Hello World, again!";
	struct mq_attr attr;
	attr.mq_msgsize = strlen(data);
	mqd = mq_open(name, O_RDWR | O_CREAT, 
			S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH, NULL);
	if (mqd == -1) {
		printf("errno: %d\n", errno);
		perror("open failed!!!: ");
		return 0;
	}
	mq_send(mqd, name, strlen(name), PRIOLOW);
	mq_send(mqd, data, strlen(data), PRIOHIGH);
	mq_send(mqd, data_new, strlen(data_new), PRIOHIGH);
	mq_close(mqd);
	return 0;
}

接收端:
/* client.c */
#include <stdio.h>

#include <fcntl.h>           /* For O_* constants */
#include <sys/stat.h>        /* For mode constants */
#include <mqueue.h>

#include <string.h>

#define PATHNAME "/msg_test"
#define PRIO 1

int main()
{
	mqd_t mqd;
	char name[24] = "/msg_test";
	struct mq_attr attr;
	char data[32];
	int prio;
	int len;

	mqd = mq_open(name, O_RDONLY, 
			S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH, NULL);
	mq_getattr(mqd, &attr);
	if (mqd == -1) {
		printf("open failed!!!\n");
		return 0;
	}
	len = mq_receive(mqd, data, attr.mq_msgsize, &prio);
	data[len] = '\0';
	mq_close(mqd);
	printf("msg: %s, msg_len: %d, prio: %d\n", data, attr.mq_msgsize, prio);
	return 0;
}

执行结果:
$ gcc -g -o server server.c -lrt
$ gcc -g -o client client.c -lrt
$ ./server
$ cat /dev/mqueue/msg_test
QSIZE:112        NOTIFY:0     SIGNO:0     NOTIFY_PID:0

$ ./client
msg: Hello World!, msg_len: 8192, prio: 2
$ ./client
msg: Hello World, again!, msg_len: 8192, prio: 2
$ ./client
msg: /msg_test, msg_len: 8192, prio: 1
$ cat /dev/mqueue/msg_test
QSIZE:24         NOTIFY:0     SIGNO:0     NOTIFY_PID:0





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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值