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

3
我正在设计一个单进程多线程嵌入式Linux应用程序。该设计包括客户端-服务器子系统,其中工作线程接收其他线程在POSIX消息队列上发布的消息。
我需要队列表现出非阻塞发送和阻塞接收语义。我可以想到几种实现以上目标的方法: - 为了访问队列而创建两个分离的消息队列描述,即调用mq_open两次。接下来,将用于通过队列发送的描述设置O_NONBLOCK标志。
  • 指定阻塞行为并使用mq_timedsend代替mq_send

  • 指定阻塞行为并在mq_send之前调用mq_getattr以避免发送时阻塞

第一种解决方案可能是首选,但是为了使其起作用,必须保证每次调用mq_open都会创建一个新的消息队列描述对象(我还假设进程中的线程可以使用多个这样的对象对同一队列执行操作)。

POSIX似乎提供了这样的保证(https://pubs.opengroup.org/onlinepubs/009695399/functions/mq_open.html),但Linux文档并没有明确说明每次调用mq_open都会创建一个新的消息队列描述对象。

Linux有这样的保证吗?

谢谢。


这听起来像是数据报Unix域套接字更适合。由于它都在一个进程中,您可以使用socketpair()创建一个匿名的双向套接字对来使用。或者只需使用无锁队列数据结构。 - Shawn
你考虑过使用ZeroMQ吗?使用inproc传输方式意味着它避免了在内核中复制数据,因此可能比Posix消息队列更快。它还具有所有可能需要的语义/传输/模式。 - bazza
1个回答

3
我需要队列表现出非阻塞发送和阻塞接收语义。
您可以在阻塞队列上使用 mq_timedsend,并带有已过期的超时时间(例如 abs_timeout{0, 0}),这使得调用在队列已满时立即返回(而不是阻塞)。
我正在设计一个单进程多线程的嵌入式Linux应用程序。该设计包括客户端-服务器子系统,其中工作线程接收其他线程在POSIX消息队列上发布的消息。
消息队列将数据复制到内核中并返回。在线程之间通信时不需要这样做。您可以使用带有互斥锁和条件变量的队列,类似于当您使用消息队列时内核为您执行的操作,但是使用自己的队列,您可以避免将数据复制到内核并返回。
我需要队列表现出非阻塞发送和阻塞接收语义。
非阻塞的mq_send仅意味着当队列已满时它不会被阻塞。
内核使用自旋锁来保护消息队列(内部),并且该自旋锁在mq_send和mq_receive上被锁定,因此从并发数据结构的角度来看,POSIX消息队列是一个阻塞数据结构。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接