Message Queue
https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/mqueue.h.html
Defines
-
MQ_PRIO_MAX (32u)
Priority levels; valid msg_prio is [0, MQ_PRIO_MAX-1].
Typedefs
-
typedef void *mqd_t
Message queue descriptor.
Functions
-
mqd_t mq_open(const char *name, int oflag, mode_t mode, struct mq_attr *attr)
Open an existing message queue or create a new one, returning a descriptor for subsequent send and receive operations.
Queues are looked up by name and allocated on demand from the kernel heap. A new queue uses a default attribute set (10 messages of 256 bytes) when
attris NULL. Storage for allmq_maxmsgmessages is reserved when the queue is created, so a call with attributes within the ranges below can still fail with ENOMEM. A failed call allocates nothing.Error numbers:
EINVAL if the name is NULL.
EINVAL if the oflag is invalid.
EINVAL if O_CREAT is specified,
attris not NULL, and mq_maxmsg is outside [1, 255] or mq_msgsize is outside [1, 16777215].ENAMETOOLONG if O_CREAT is specified and the name is longer than 16 characters. Without O_CREAT such a name reports ENOENT.
EEXIST if the queue exists and both O_CREAT and O_EXCL are specified.
ENOMEM if there is insufficient memory for the descriptor, message queue, or name.
ENOENT if the queue does not exist and O_CREAT is not specified.
Note
Name resolution is O(N) in the number of message queues that currently exist. This is a setup-time operation and is NOT part of the kernel’s O(1) operational guarantee. The operational calls - mq_send(), mq_receive(), mq_getattr(), mq_close() - are O(1), independent of the number of queues or threads in the system.
- Parameters:
name – Name of the message queue.
oflag – One of the access mode flags:
O_RDONLY : Open the queue to receive messages only.
O_WRONLY : Open the queue to send messages only.
O_RDWR : Open the queue for reading and writing. And optionally OR’ed with:
O_CREAT : Create the queue if it does not exist.
O_EXCL : If O_CREAT is also specified, and a queue with the given name already exists, then mq_open() will fail.
O_NONBLOCK : Open this descriptor in non-blocking mode.
mode – Not supported.
attr – Attributes of a new queue; only
mq_maxmsgandmq_msgsizeare used. NULL for default attributes.
- Returns:
mqd_t Message queue descriptor on success, (mqd_t)-1 on error and errno set.
void *producer(void *arg) { struct mq_attr attr = { .mq_maxmsg = 8, .mq_msgsize = sizeof(uint32_t) }; uint32_t value = 0u; mqd_t mq; (void)arg; mq = mq_open("/data", O_CREAT | O_WRONLY, 0, &attr); if (mq != (mqd_t)-1) { for (;;) { value++; (void)mq_send(mq, (const char *)&value, sizeof(value), 0u); } } return NULL; }
-
int mq_notify(mqd_t mqdes, const struct sigevent *notification)
Not supported.
- Returns:
-1 and sets errno to ENOSYS.
-
int mq_setattr(mqd_t mqdes, const struct mq_attr *mqstat, struct mq_attr *omqstat)
Update the per-descriptor flags of an open message queue.
Only the O_NONBLOCK bit of
mq_flagsis honored; the other fields ofmqstatare ignored. The change applies tomqdesonly, not to other descriptors of the same queue. Whenomqstatis non-NULL it receives the attributes as mq_getattr() reported them before the update, so itsmq_flagsis the descriptor’s previous O_NONBLOCK setting.Error numbers:
- Parameters:
mqdes – Message queue descriptor.
mqstat – New message queue attributes.
omqstat – Old message queue attributes.
- Returns:
0 on success, -1 on error and errno set.
-
int mq_getattr(mqd_t mqdes, struct mq_attr *mqstat)
Copy the attributes of an open message queue into
mqstat.mq_maxmsg,mq_msgsizeandmq_curmsgsare those of the queue.mq_flagsis that of the descriptor: O_NONBLOCK whenmqdesis non-blocking (set by mq_open() or mq_setattr()) and 0 otherwise. No other flag is reported.Error numbers:
- Parameters:
mqdes – Message queue descriptor.
mqstat – Message queue attributes.
- Returns:
0 on success, -1 on error and errno set.
-
int mq_send(mqd_t mqdes, const char *msg_ptr, size_t msg_len, unsigned msg_prio)
Append a message to a queue, waiting indefinitely if the queue is full and the descriptor is in blocking mode.
Equivalent to mq_timedsend() with a NULL deadline. When QRT_CFG_DEFER_ENABLE is enabled the call may also be made from a deferred function or a timer callback (see qrt_defer_call()), on a descriptor with O_NONBLOCK set.
Error numbers:
EAGAIN if the queue is full and O_NONBLOCK is set.
EINVAL if msg_ptr is NULL.
EINVAL if msg_prio is not less than MQ_PRIO_MAX.
EMSGSIZE if msg_len is 0 or exceeds the queue’s message size.
EBADF if the descriptor is invalid or not opened for writing, or the call is made from a deferred function or a timer callback without O_NONBLOCK set (a debug build asserts instead).
- Parameters:
mqdes – Message queue descriptor.
msg_ptr – Pointer to the message to be sent.
msg_len – Length of the message.
msg_prio – Message priority in [0, MQ_PRIO_MAX-1]. Higher-priority messages are received first; equal priorities stay FIFO.
- Returns:
0 on success, -1 on error and errno set.
-
int mq_timedsend(mqd_t mqdes, const char *msg_ptr, size_t msg_len, unsigned msg_prio, const struct timespec *abstime)
Append a message to a queue, waiting at most until
abstime(CLOCK_REALTIME) when the queue is full.If the descriptor has O_NONBLOCK set the call never blocks regardless of
abstime. When QRT_CFG_DEFER_ENABLE is enabled the call may also be made from a deferred function or a timer callback (see qrt_defer_call()), on a descriptor with O_NONBLOCK set. This and mq_send() are the only message queue services available there.Error numbers:
EAGAIN if the queue is full and O_NONBLOCK is set.
EINVAL if msg_ptr is NULL.
EINVAL if msg_prio is not less than MQ_PRIO_MAX.
EINVAL if the thread would have to wait and
abstimehas nanoseconds outside [0, 999’999’999].EMSGSIZE if msg_len is 0 or exceeds the queue’s message size.
EBADF if the descriptor is invalid or not opened for writing, or the call is made from a deferred function or a timer callback without O_NONBLOCK set (a debug build asserts instead).
ETIMEDOUT if the queue is full and
abstimehas passed (negative seconds lie before the epoch, and {0, 0} is the epoch), or passes before a slot frees.
- Parameters:
mqdes – Message queue descriptor.
msg_ptr – Pointer to the message to be sent.
msg_len – Length of the message.
msg_prio – Message priority in [0, MQ_PRIO_MAX-1]. Higher-priority messages are received first; equal priorities stay FIFO.
abstime – Pointer to the absolute time (CLOCK_REALTIME) to wait until when the queue is full.
- Returns:
0 on success, -1 on error and errno set.
-
ssize_t mq_receive(mqd_t mqdes, char *msg_ptr, size_t msg_len, unsigned *msg_prio)
Remove the highest-priority message (the oldest of equal priority) from a queue, waiting indefinitely if it is empty and the descriptor is in blocking mode.
Equivalent to mq_timedreceive() with a NULL deadline, so the call must likewise be made from a thread.
Error numbers:
EAGAIN if the queue is empty and O_NONBLOCK is set.
EINVAL if msg_ptr is NULL.
EMSGSIZE if msg_len is smaller than the queue’s message size.
EBADF if the descriptor is invalid or not opened for reading.
- Parameters:
mqdes – Message queue descriptor.
msg_ptr – Pointer to the buffer that will receive the message.
msg_len – Size of the receive buffer.
msg_prio – If non-NULL, set to the priority of the received message.
- Returns:
Message length in bytes on success, -1 on error and errno set.
-
ssize_t mq_timedreceive(mqd_t mqdes, char *msg_ptr, size_t msg_len, unsigned *msg_prio, const struct timespec *abstime)
Remove the highest-priority message (the oldest of equal priority) from a queue, waiting at most until
abstime(CLOCK_REALTIME) when the queue is empty.If the descriptor has O_NONBLOCK set the call never blocks regardless of
abstime. Unlike mq_timedsend(), the call must be made from a thread, never from a deferred function or a timer callback, even on a descriptor with O_NONBLOCK set.Error numbers:
EAGAIN if the queue is empty and O_NONBLOCK is set.
EINVAL if msg_ptr is NULL.
EINVAL if the thread would have to wait and
abstimehas nanoseconds outside [0, 999’999’999].EMSGSIZE if msg_len is smaller than the queue’s message size.
EBADF if the descriptor is invalid or not opened for reading.
ETIMEDOUT if the queue is empty and
abstimehas passed (negative seconds lie before the epoch, and {0, 0} is the epoch), or passes before a message arrives.
- Parameters:
mqdes – Message queue descriptor.
msg_ptr – Pointer to the buffer that will receive the message.
msg_len – Size of the receive buffer.
msg_prio – If non-NULL, set to the priority of the received message.
abstime – Pointer to the absolute time (CLOCK_REALTIME) to wait until when the queue is empty.
- Returns:
Message length in bytes on success, -1 on error and errno set.
static uint32_t total; static unsigned int timeouts; void *consumer(void *arg) { struct timespec deadline; uint32_t value; mqd_t mq; (void)arg; mq = mq_open("/data", O_RDONLY, 0, NULL); if (mq != (mqd_t)-1) { for (;;) { (void)clock_gettime(CLOCK_REALTIME, &deadline); deadline.tv_sec += 1; if (mq_timedreceive(mq, (char *)&value, sizeof(value), NULL, &deadline) > 0) { total += value; } else if (errno == ETIMEDOUT) { timeouts++; } } } return NULL; }
-
int mq_unlink(const char *name)
Remove a message queue’s name from the registry, deferring deletion until the last descriptor is closed.
If no descriptors remain at the time of the call the queue and its backing memory are released immediately; otherwise the queue is marked unlinked and destroyed when mq_close() drops the last reference. Until then the descriptors still open keep working as before, and the unlink does not change the attributes mq_getattr() reports for them.
Error numbers:
EINVAL if
nameis NULL.ENAMETOOLONG if
nameis longer than 16 characters.ENOENT if the message queue does not exist.
- Parameters:
name – Name of the message queue.
- Returns:
0 on success, -1 on error and errno set.
-
struct mq_attr
- #include <mqueue.h>
Message queue attributes.