POSIX Message Queues
This chapter describes POSIX message queues, which allow processes to exchange data in the form of messages
POSIX message queues are similar to their System V counterparts, in that data is exchanged in units of whole messages
However, there are also some notable differences:
- POSIX message queues are reference counted. A queue that is marked for deletion is removed only after it is closed by all processes that are currently using it.
- Each System V message has an integer type, and messages can be selected in a
variety of ways using
msgrcv(). By contrast, POSIX messages have an associated priority, and messages are always strictly queued (and thus received) in priority order. - POSIX message queues provide a feature that allows a process to be asynchronously notified when a message is available on a queue.
52.1 Overview
The main functions in the POSIX message queue API are the following:
- The
mq_open()function creates a new message queue or opens an existing queue, returning a message queue descriptor for use in later calls. - The
mq_send()function writes a message to a queue. - The
mq_receive()function reads a message from a queue. - The
mq_close()function closes a message queue that the process previously opened. - The
mq_unlink()function removes a message queue name and marks the queue for deletion when all processes have closed it
The above functions all serve fairly obvious purposes. In addition, a couple of features are peculiar to the POSIX message queue API:
- Each message queue has an associated set of attributes. Some of these
attributes can be set when the queue is created or opened using
mq_open(). Two functions are provided to retrieve and change queue attributes:mq_getattr()andmq_setattr(). - The
mq_notify()function allows a process to register for message notification from a queue. After registering, the process is notified of the availability of a message by delivery of a signal or by the invocation of a function in a separate thread.
52.2 Opening, Closing, and Unlinking a Message Queue
However, if O_CREAT is specified in flags, two further arguments
are required: mode and attr.
mq_queue 两种模式,打开和创建
Upon successful completion, mq_open() returns a message queue descriptor, a value of
type mqd_t, which is used in subsequent calls to refer to this open message queue.
所以 message queue 不像其他的 IPC 机制那样,使用 key_t 创建,而是使用
char * name
52.3 Relationship Between Descriptors and Message Queues
The relationship between a message queue descriptor and an open message queue is analogous to the relationship between a file descriptor and an open file
On Linux, POSIX message queues are implemented as i-nodes in a virtual file system, and message queue descriptors and open message queue descriptions are implemented as file descriptors and open file descriptions, respectively
- Two processes can hold message queue descriptors (descriptor x in the diagram) that refer to the same open message queue description. This can occur because a process opens a message queue and then calls fork(). These descriptors share the state of the O_NONBLOCK flag.
- Two processes can hold open message queue descriptors that refer to different message queue descriptions that refer to the same message queue (e.g., descriptor z in process A and descriptor y in process B both refer to /mq-r). This occurs because the two processes each used mq_open() to open the same queue.
52.4 Message Queue Attributes
struct mq_attr {
long mq_flags; /* Message queue description flags: 0 or
O_NONBLOCK [mq_getattr(), mq_setattr()] */
long mq_maxmsg; /* Maximum number of messages on queue
[mq_open(), mq_getattr()] */
long mq_msgsize; /* Maximum message size (in bytes)
[mq_open(), mq_getattr()] */
long mq_curmsgs; /* Number of messages currently in queue
[mq_getattr()] */
}
接下来分析了几个例子
52.5 Exchanging Message
介绍 mq_send 和 mq_receive 的使用,并且演示了一个例子,说明 block 的含义
If the message queue is already full (i.e., the mq_maxmsg limit for the queue has
been reached), then a further mq_send() either blocks until space becomes available
in the queue, or, if the O_NONBLOCK flag is in effect, fails immediately with the error
EAGAIN.
The mq_timedsend() and mq_timedreceive() functions are exactly like mq_send() and
mq_receive(), except that if the operation can’t be performed immediately, and the
O_NONBLOCK flag is not in effect for the message queue description, then the
abs_timeout argument specifies a limit on the time for which the call will block.
52.6 Message Notification
The sigev_notify field of this structure is set to one of the following values:
下面分别讲解三个取值的含义 SIGEV_NONE SIGEV_SIGNAL SIGEV_THREAD 但是没有看
52.6.1 Receiving Notification via a Signal
skip
52.6.2 Receiving Notification via a Thread
skip
问题
If oflag includes O_CREAT, a new, empty
queue is created if one with the given name doesn’t already exist. If oflag specifies
both O_CREAT and O_EXCL, and a queue with the given name already exists, then
mq_open() fails.
似乎这两个标志反复的说明出现,但是有一种情况没有说明: 当 queue 已经出现, 没有 O_EXCL 会出现什么情况。 创建两个 queue ? 报错 ?(如何报错,那么 O_EXCL 就没有意义了
本站所有文章转发 CSDN 将按侵权追究法律责任,其它情况随意。