ipc · medium

IPC: POSIX Message Queues — Priority-Ordered Framed Messages

POSIX message queues (mq_open) are kernel-managed named queues under /dev/mqueue. mq_send(mq, msg, len, priority) enqueues a discrete message with a priority. mq_receive returns the highest-priority message (ties: FIFO within priority). Unlike pipes: message framing is automatic (no length-prefix needed), priority is built-in. Blocks when full (mq_send) or empty (mq_receive); use O_NONBLOCK + EAGAIN to avoid blocking. mq_notify: receive an async signal (SIGEV_SIGNAL) or thread callback (SIGEV_THREAD) when the queue transitions from empty to non-empty — must re-register after each notification. mq_unlink removes the name; attributes (mq_maxmsg, mq_msgsize) set at creation. Link with -lrt on Linux. Use for: alerting systems, job queues, event prioritization.

🔑 Key line

mq_open('/name') + mq_send(priority) + mq_receive() — persistent named queue, priority-ordered messages; always dequeues highest priority first; blocks when full (write) or empty (read); mq_notify for async arrival; mq_unlink to remove; link with -lrt.

The code

// POSIX Message Queue — typed messages + priority + async notify
#include <mqueue.h>
// Sender process
struct mq_attr attr{};
attr.mq_maxmsg = 10; // max messages in queue
attr.mq_msgsize = 256; // max bytes per message
mqd_t mq = mq_open("/myqueue", O_CREAT | O_WRONLY, 0644, &attr);
// Priority: higher number = higher priority = dequeued first
mq_send(mq, "CRITICAL: CPU >90%", 18, 10); // priority 10
mq_send(mq, "WARN: mem 80%", 13, 5); // priority 5
mq_send(mq, "INFO: heartbeat", 15, 1); // priority 1
mq_close(mq);
// Receiver process — gets highest priority first
mqd_t mq = mq_open("/myqueue", O_RDONLY);
char buf[256];
unsigned int prio;
mq_receive(mq, buf, sizeof(buf), &prio);
// → buf = "CRITICAL: CPU >90%", prio = 10
mq_receive(mq, buf, sizeof(buf), &prio);
// → buf = "WARN: mem 80%", prio = 5
mq_close(mq);
mq_unlink("/myqueue"); // remove from /dev/mqueue
// Async notification — signal when message arrives
struct sigevent sev{};
sev.sigev_notify = SIGEV_SIGNAL;
sev.sigev_signo = SIGUSR1;
mq_notify(mq, &sev); // MUST re-register after each!
// Or: SIGEV_THREAD to call a function in a new thread

What this lesson walks through

  1. 01mq_open — create a persistent named queue
  2. 02mq_send with priority — highest priority dequeued first
  3. 03Queue with 3 messages — sorted by priority
  4. 04mq_receive — dequeues highest priority first
  5. 05Queue full — mq_send blocks
  6. 06mq_notify — async SIGEV_SIGNAL or SIGEV_THREAD

mq_open('/myqueue', O_CREAT|O_WRONLY) creates a named message queue under /dev/mqueue. Unlike pipes, it persists until mq_unlink() even if all processes close it. It has a name — any process can open it by that name. Set mq_maxmsg and mq_msgsize limits.

See it animated — step by step, at your own pace

Unlock the full interactive walkthrough of IPC: POSIX Message Queues — Priority-Ordered Framed Messages and 100+ animated C++ interview lessons.

← Previous
IPC: Shared Memory — Zero-Copy Direct Memory Access Between Processes
Next →
IPC: Signals & sigaction — Async Notifications, Masks, and Handler Safety