POSIX vs System V Message Queues in Linux

Inter-process communication (IPC) in the Linux operating system relies heavily on message queues, with the two primary standards being System V and POSIX. While both mechanisms allow processes to exchange structured data asynchronously, Linux implements them using fundamentally different architectural designs. This article examines the core implementation differences between POSIX and System V message queues in Linux, covering kernel-level abstraction, file descriptor integration, message prioritization, and asynchronous event notification.

Kernel Abstraction and Filesystem Integration

The primary structural divergence between the two implementations lies in how Linux represents them within the kernel.

POSIX message queues are implemented in Linux as a dedicated virtual file system (mqueuefs), typically mounted at /dev/mqueue. Because of this design, queues are named using standard slash-prefixed paths (e.g., /my_queue) and behave similarly to files. Developers can inspect, monitor, and remove queues using standard shell utilities such as ls, cat, and rm.

In contrast, System V message queues exist entirely outside the Linux Virtual File System (VFS). They are identified by arbitrary integer keys generated via ftok() or IPC_PRIVATE and assigned an IPC identifier by the kernel. System V queues reside in global kernel memory tables and require specialized administrative tools, such as ipcs and ipcrm, to inspect and manipulate.

File Descriptors and I/O Multiplexing

Because POSIX message queues are integrated into the Linux VFS, the descriptor returned by mq_open (mqd_t) can be converted or treated as a standard file descriptor in Linux. This architectural choice enables seamless integration with modern Linux I/O multiplexing interfaces, including select(), poll(), and epoll(). Systems handling high-throughput event loops can monitor POSIX message queues alongside network sockets and file handles without dedicated worker threads.

System V message queues do not use file descriptors. The identifier returned by msgget() is strictly an internal index to a kernel IPC table. As a result, System V queues cannot be monitored directly with epoll or select. To process incoming messages, applications must either perform blocking calls on msgrcv() or continuously poll the queue in non-blocking mode, consuming unnecessary CPU cycles.

Asynchronous Notification

Linux provides built-in asynchronous notification capabilities for POSIX message queues via the mq_notify() system call. This mechanism allows an application to register for a one-time notification when a message arrives on an empty queue. The kernel can deliver this notification either by generating a specified signal (such as SIGUSR1 or a real-time signal) or by instantiating a new thread inside the receiving process via POSIX threads (pthread).

System V provides no equivalent event-driven notification mechanism. Processes must block inside the kernel waiting for data via msgrcv() or implement custom signaling abstractions around the queue operations.

Priority Handling and Message Retrieval

Message ordering and retrieval logic also differ significantly between the two interfaces:

Resource Limits and Management

Linux enforces resource controls on both mechanisms, but applies them differently: