简体   繁体   English

使用 POSIX 消息队列进行进程内通信

[英]Using POSIX message queues for intra-process communication

I am designing a single-process multi-threaded embedded Linux application.我正在设计一个单进程多线程嵌入式 Linux 应用程序。 The design includes client-server subsystem where a worker thread receives messages posted by other threads on a POSIX message queue.该设计包括客户端-服务器子系统,其中一个工作线程接收其他线程在 POSIX 消息队列上发布的消息。

I need the queue to exhibit non-blocking send and blocking receive semantics.我需要队列表现出非阻塞发送和阻塞接收语义。 I can think of several ways to achieve the above: - Creating two separate message queue descriptions for accessing the queue for the sake of send and receive, that is calling mq_open twice.我可以想到几种方法来实现上述目的: - 创建两个单独的消息队列描述用于为了发送和接收而访问队列,即调用 mq_open 两次。 This will be followed by setting the O_NONBLOCK flag of the description that will be used for sending via the queue.这之后将设置将用于通过队列发送的描述的 O_NONBLOCK 标志。

  • Specifying blocking behavior and using mq_timedsend in lieu of mq_send指定阻塞行为并使用 mq_timedsend 代替 mq_send

  • Specifying blocking behavior and calling mq_getattr before mq_send to avoid blocking on send指定阻塞行为并在 mq_send 之前调用 mq_getattr 以避免阻塞发送

The first solution is probably the preferred one, however for this to work it must be guaranteed that each call to mq_open creates a new message queue description object (I am also assuming that threads in a process can use multiple such objects to perform operation on the same queue).第一个解决方案可能是首选的解决方案,但是要使其工作,必须保证每次调用 mq_open 都会创建一个新的消息队列描述对象(我还假设进程中的线程可以使用多个这样的对象来对相同的队列)。

POSIX seems to provide such a guarantee ( https://pubs.opengroup.org/onlinepubs/009695399/functions/mq_open.html ) however Linux documentation does not explicitly say that each call to mq_open creates a new message queue description object. POSIX 似乎提供了这样的保证( https://pubs.opengroup.org/onlinepubs/009695399/functions/mq_open.html )但是 Linux 文档没有明确说明每次调用 mq_open 都会创建一个新的消息队列描述对象。

Is there such a guarantee for Linux? Linux有这样的保证吗?

Thanks,谢谢,

I need the queue to exhibit non-blocking send and blocking receive semantics.我需要队列表现出非阻塞发送和阻塞接收语义。

You can use mq_timedsend on a blocking queue with an expired timeout (eg abs_timeout{0, 0} ), which makes the call return immediately (not block) when the queue is full.您可以在具有过期超时(例如abs_timeout{0, 0} )的阻塞队列上使用mq_timedsend ,这使调用在队列已满时立即返回(而不是阻塞)。


I am designing a single-process multi-threaded embedded Linux application.我正在设计一个单进程多线程嵌入式 Linux 应用程序。 The design includes client-server subsystem where a worker thread receives messages posted by other threads on a POSIX message queue.该设计包括客户端-服务器子系统,其中一个工作线程接收其他线程在 POSIX 消息队列上发布的消息。

Message queues copy the data into the kernel and back.消息队列将数据复制到内核并返回。 Communicating between threads in the same process there is no need for that.在同一进程中的线程之间进行通信没有必要。 You can just use a queue with a mutex and a condition variable, that is similar to what the kernel does for you when you use message queues, but using your own queue you would avoid copying data into the kernel and back.您可以只使用带有互斥锁和条件变量的队列,这与使用消息队列时内核为您所做的类似,但是使用您自己的队列可以避免将数据复制到内核中并返回。

I need the queue to exhibit non-blocking send and blocking receive semantics.我需要队列表现出非阻塞发送和阻塞接收语义。

Non-blocking mq_send only means that it doesn't block when the queue is full.非阻塞mq_send仅意味着当队列已满时它不会阻塞。

The kernel protects the message queue with a spinlock internally and that spinlock gets locked on mq_send and mq_receive , so that from concurrent data structure point of view POSIX message queue is a blocking data structure. 内核在内部使用自旋锁保护消息队列,并且自旋锁被锁定在mq_sendmq_receive ,因此从并发数据结构的角度来看,POSIX 消息队列是一个阻塞数据结构。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM