随内核的持续性
读总是返回最高优先级的最早消息。
当往一个空队列放置一个消息时,允许产生一个信号或启动一个线程。
可认为是一个消息链表
队列中每个消息具有
1.一个无符号整数优先级
2.消息的数据部分长度(可以为0)
3.数据本身(如果长度)
链表头中为当前队列的两个属性:队列中允许的最大消息数(mq_mqxmsg)以及每个消息的最大大小(mq_msgsize)。只能在创建队列的时候设置。
MQ_OPEN_MAX一个进程能够同时拥有打开着消息队列的最大数目
MQ_PRIO_MAX任意消息的最大优先级+1
每个消息队列有一个保持其当前打开着描述符数的引用计数器,因而本函数能够实现类似于unlink函数删除一个文件的机制:当一个消息队列的引用计数仍大于0时,其name就能删除。但是该队列的析构(这与从系统中删除其名字不同)要到最后一个mq_close发生时才进行。
一个消息队列的名字在系统中的存在本身也占用其引用计数器的一个引用数。mq_unlink从系统中删除该名字意味着同时将其引用计数减1,若变为0则真正拆除该队列。跟mq_unlink一样,mq_close也将当前消息队列的引用计数减1,若变为0则附带拆除该队列。
限制:
无法向接收者准确地标识每条消息的发送者,
POSIX消息队列允许异步事件通知,以告知何时有一个消息放置到了某个空消息队列中。 有两种方式: 产生一个信号 创建一个线程来执行一个指定的函数
异步通知挺多坑的,建议看书。
异步信号安全函数:可以从信号处理程序中调用的函数。不是异步信号安全函数不可以从信号处理程序中调用。
(这个人很懒,连昵称也没有: 兄弟不要误导别人,多看看手册吧。 On Linux, a message queue descriptor is actually a file descriptor. (POSIX does not require such an implementation.) This means that a message queue descriptor can be monitored using select(2), poll(2), or epoll(7). This is not portable.)
书是10年前的书,手册是现在的手册
消息队列描述符不是“普通”描述符,它不能用在select或poll中,但我们可以巧妙的用一个管道和一个子进程实现。通过异步事件通知,把消息写入管道里。通过读取管道知晓消息队列的情况。
书上有使用内存映射I/O以及posix互斥锁和条件变量实现posix消息队列。