APUE读书笔记–POSIX消息队列
1. 概述
- 消息队列可以认为是一个消息链表,有足够的写权限的线程可以往队列中放置消息,有足够的读权限的线程可以从队列中取走消息。
- 每个消息都是一个记录(record),有一个长度和优先级。
- 消息队列具有随内核的持续性
随内核持续性:IPC对象一直存在到内核重新自举或显式删除该对象为止。
2. mq_open、mq_close、mq_unlink函数
2.1 mq_open函数
mq_open函数创建一个新的消息队列或打开一个已存在的消息队列。
#include <fcntl.h> /* For O_* constants */
#include <sys/stat.h> /* For mode constants */
#include <mqueue.h>
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);
Link with -lrt.
//返回值:若成功,则为消息队列描述符,若出错返回-1
返回值称为消息队列描述符,不必是向文件描述符或套接字这样的短整形。
Linux内核将mqd_t 定义为 int类型:
typedef __kernel_mqd_t mqd_t;
typedef int __kernel_mqd_t;name命名规则
- 必须符合已有的路径名规则(必须最多由PATH_MAX个字节构成,包括结尾的空字节)
- 如果它以斜杠开头,那么对这些函数的不同调用将访问同一个队列。
- 名字中额外的斜杠符的解释由实现定义。为了可移植性,IPC名字必须以一个斜杠开头,并且不能包含其他的斜杠符。
- oflag参数必须指定或O_WRONLY或O_RDONLY或O_RDWR标志,还可以指定O_CREAT、O_EXCL、O_TRUNC标志。
- 如果指定O_CREAT标志,则需要指定mode和attr值,attr值为NULL则使用默认属性。
2.2 mq_close函数
mq_close函数关闭已打开的消息队列
#include <mqueue.h>
int mq_close(mqd_t mqdes);
//返回值:若成功则为0,若出错则为-1
- 调用进程可以不在使用该描述符,但是其消息队列并不从系统中删除。一个进程终止时,它的所有打开着的消息队列都关闭。这与close函数类似。
2.3 mq_unlink函数
要从系统中删除用作mq_open第一个参数的name,必须调用mq_unlink
#include <mqueue.h>
int mq_unlink(const char *name);
//返回值:若成功,返回0,若出错则为-1
- 当一个消息队列的引用计数仍大于0时,其name就能删除。与unlink函数删除一个文件的机制类似。
2.4 函数例子
创建一个消息队列
#include "unpipc.h"
int main(int argc, char *argv[])
{
int c, flags;
mqd_t mqd;
flags = O_CREAT | O_RDWR;
while((c = getopt(argc, argv, "e")) != -1) { //getopt函数读主函数参数,从第一个开始读,如果有-e选项,则flags|= O_EXCL
switch (c) {
case 'e':
flags |= O_EXCL;
break;
}
}
if(optind != argc - 1)
sys_err("usage: ./a.out [ -e ] <name>");
mqd = mq_open(argv[optind], flags, FILE_MODE, NULL);
if(mqd == -1) {
sys_err("mq_open err");
}
printf("mqd = %d\n", mqd);
mq_close(mqd);
return <