Linux 中的消息队列已经过时了吗?

发布于 2024-07-22 20:34:29 字数 964 浏览 4 评论 0原文

我最近一直在 Linux 中使用消息队列(System V,但 POSIX 也应该可以),它们似乎非常适合我的应用程序,但是在阅读了《Unix 编程的艺术》之后,我不确定它们是否真的是一个不错的选择。

http://www.faqs.org/docs/artu/ch07s02.html#id2922148

System V IPC 的上层消息传递层已基本不再使用。 下层由共享内存和信号量组成,在需要在同一台机器上运行的进程之间进行互斥锁定和一些全局数据共享的情况下仍然具有重要的应用。 这些 System V 共享内存设施演变成 POSIX 共享内存 API,在 Linux、BSD、MacOS X 和 Windows 下受支持,但不支持经典 MacOS。

http://www.faqs.org/docs/artu/ch07s03.html#id2923376

System V IPC 设施存在于 Linux 和其他现代 Unix 中。 然而,由于它们是遗留功能,因此不会经常使用。 截至 2003 年中期,Linux 版本仍存在缺陷。 似乎没有人足够关心来修复它们。

在较新的 Linux 版本中,System V 消息队列是否仍然存在错误? 我不确定作者是否意味着 POSIX 消息队列应该没问题?

似乎套接字是几乎所有东西的首选 IPC(?),但我看不出使用套接字或其他东西来实现消息队列是多么简单。 还是我想得太复杂了?

我不知道我正在使用嵌入式 Linux 是否相关?

I've been playing with message queues (System V, but POSIX should be ok too) in Linux recently and they seem perfect for my application, but after reading The Art of Unix Programming I'm not sure if they are really a good choice.

http://www.faqs.org/docs/artu/ch07s02.html#id2922148

The upper, message-passing layer of System V IPC has largely fallen out of use. The lower layer, which consists of shared memory and semaphores, still has significant applications under circumstances in which one needs to do mutual-exclusion locking and some global data sharing among processes running on the same machine. These System V shared memory facilities evolved into the POSIX shared-memory API, supported under Linux, the BSDs, MacOS X and Windows, but not classic MacOS.

http://www.faqs.org/docs/artu/ch07s03.html#id2923376

The System V IPC facilities are present in Linux and other modern Unixes. However, as they are a legacy feature, they are not exercised very often. The Linux version is still known to have bugs as of mid-2003. Nobody seems to care enough to fix them.

Are the System V message queues still buggy in more recent Linux versions? I'm not sure if the author means that POSIX message queues should be ok?

It seems that sockets are the preferred IPC for almost anything(?), but I cannot see how it would be very simple to implement message queues with sockets or something else. Or am I thinking too complexly?

I don't know if it's relevant that I'm working with embedded Linux?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

乙白 2024-07-29 20:34:29

就我个人而言,我非常喜欢消息队列,并且认为它们可以说是 Unix 世界中利用率最低的 IPC。 它们快速且易于使用。

一些想法:

  • 其中一些只是时尚。 旧事物又变成新的了。 在消息队列上添加一个闪亮的do-dad,它们可能是明年最新、最热门的东西。 看看 Google 的 Chrome,它的选项卡使用单独的进程而不是线程。 突然间,人们感到很兴奋,因为当一个选项卡锁定时,它不会导致整个浏览器瘫痪。

  • 共享内存带有某种希曼光环。 如果您没有从机器中挤出最后一个周期并且 MQ 的效率稍低,那么您就不是一个“真正的”程序员。 对于许多(如果不是大多数)应用程序来说,这完全是无稽之谈,但有时一旦形成思维定势就很难打破。

  • MQ 确实不适合具有无限数据的应用程序。 面向流的机制(例如管道或套接字)更容易使用。

  • System V 变体确实已经失宠了。 作为一般规则,尽可能使用 POSIX 版本的 IPC。

Personally I am quite fond of message queues and think they are arguably the most under-utilized IPC in the unix world. They are fast and easy to use.

A couple of thoughts:

  • Some of this is just fashion. Old things become new again. Add a shiny do-dad on message queues and they may be next year's newest and hottest thing. Look at Google's Chrome using separate processes instead of threads for its tabs. Suddenly people are thrilled that when one tab locks up it doesn't bring down the entire browser.

  • Shared memory has something of a He-man halo about it. You're not a "real" programmer if you aren't squeezing that last cycle out of the machine and MQs are marginally less efficient. For many, if not most apps, it is utter nonsense but sometimes it is hard to break a mindset once it takes hold.

  • MQs really aren't appropriate for applications with unbounded data. Stream oriented mechanisms like pipes or sockets are just easier to use for that.

  • The System V variants really have fallen out of favor. As a general rule go with POSIX versions of IPC when you can.

蓝梦月影 2024-07-29 20:34:29

是的,我认为消息队列适合某些应用程序。 POSIX 消息队列提供了更好的接口,特别是,您可以为队列提供名称而不是 ID,这对于故障诊断非常有用(可以更轻松地看出哪个是哪个)。

Linux 允许您将 posix 消息队列挂载为文件系统,并使用“ls”查看它们,使用“rm”删除它们,这也很方便(系统 V 依赖于笨重的“ipcs”和“ipcrm”命令)

Yes, I think that message queues are appropriate for some applications. POSIX message queues provide a nicer interface, in particular, you get to give your queues names rather than IDs, which is very useful for fault diagnosis (makes it easier to see which is which).

Linux allows you to mount the posix message queues as a filesystem and see them with "ls", delete them with "rm" which is quite handy too (System V depends on the clunky "ipcs" and "ipcrm" commands)

幸福丶如此 2024-07-29 20:34:29

我实际上并没有使用 POSIX 消息队列,因为我总是想保留通过网络分发消息的选项。 考虑到这一点,您可能会考虑更强大的消息传递接口,例如 zeromq 或实现 AMQP

0mq 的优点之一是,当在多线程应用程序中的同一进程空间中使用时,它使用非常快的无锁零复制机制。 不过,您也可以使用相同的接口通过网络传递消息。

I haven't actually used POSIX message queues because I always want to leave open the option to distribute my messages across a network. With that in mind, you might look at a more robust message-passing interface like zeromq or something that implements AMQP.

One of the nice things about 0mq is that when used from the same process space in a multithreaded app, it uses a lockless zero-copy mechanism that is quite fast. Still, you can use the same interface to pass messages over a network as well.

电影里的梦 2024-07-29 20:34:29

POSIX消息队列最大的缺点:

  • POSIX消息队列没有要求select()兼容。(它与select()一起使用code> 在 Linux 中但不在 Qnx 系统中)
  • 它有惊喜。

Unix 数据报套接字执行与 POSIX 消息队列相同的任务。 Unix数据报套接字工作在套接字层。 可以将其与 select()/poll() 或其他 IO 等待方法一起使用。 在设计基于事件的系统时,使用select()/poll()具有优势。 通过这种方式可以避免繁忙循环。

消息队列中有惊喜。 考虑一下mq_notify()。 它用于获取接收事件。 听起来我们可以通知一些有关消息队列的信息。 但它实际上是注册通知而不是通知任何东西。

关于 mq_notify() 更令人惊讶的是,它必须在每次 mq_receive() 之后调用,这可能会导致竞争条件(当其他进程/线程调用>mq_send() 调用 mq_receive()mq_notify() 之间)。

它有一整套 mq_open、mq_send()、mq_receive() 和 mq_close() 以及它们自己的定义,这是多余的,在某些情况下与套接字 open()、send( ),recv() 和 close() 方法规范。

我认为消息队列不应该用于同步。 eventfdsignalfd 适合于此。

但是它(POSIX消息队列)有一些实时支持。 它具有优先功能。

Messages are placed on the queue in decreasing order of priority, with newer messages of the same priority being placed after older messages with the same priority.

但是这个优先级也可用于套接字作为带外数据!

最后,对我来说,POSIX 消息队列是一个遗留 API。 只要不需要实时功能,我总是更喜欢 Unix 数据报套接字而不是 POSIX 消息队列。

Biggest disadvantages of POSIX message queue:

  • POSIX message queue does not make it a requirement to be compatible with select().(It works with select() in Linux but not in Qnx system)
  • It has surprises.

Unix Datagram socket does the same task of POSIX message queue. And Unix Datagram socket works in socket layer. It is possible to use it with select()/poll() or other IO-wait methods. Using select()/poll() has the advantage when designing event-based system. It is possible to avoid busy loop in that way.

There is surprise in message queue. Think about mq_notify(). It is used to get receive-event. It sounds like we can notify something about the message queue. But it is actually registering for notification instead of notifying anything.

More surprise about mq_notify() is that it has to be called after every mq_receive(), which may cause a race-condition(when some other process/thread call mq_send() between the call of mq_receive() and mq_notify()).

And it has a whole set of mq_open, mq_send(), mq_receive() and mq_close() with their own definition which is redundant and in some case inconsistent with socket open(),send(),recv() and close() method specification.

I do not think message queue should be used for synchronization. eventfd and signalfd are suitable for that.

But it(POSIX message queue) has some realtime support. It has priority features.

Messages are placed on the queue in decreasing order of priority, with newer messages of the same priority being placed after older messages with the same priority.

But this priority is also available for socket as out-of-band data !

Finally, to me , POSIX message queue is a legacy API. I always prefer Unix Datagram socket instead of POSIX message queue as long as the real-time features are not needed.

戏剧牡丹亭 2024-07-29 20:34:29

消息队列对于构建本地解耦应用程序非常有用。 它们非常快,它们是块组织的(不需要缓冲、切割等,这是流式套接字的情况),基本上很少有 memcpy() 操作(用户代码将块复制到内核,以及内核将块复制到其他进程读取) q),这就是消息传递的故事。 一些业界知名的中间件(例如 Oracle Tuxedo 或 Mavimax Enduro/X)使用这些队列来帮助构建负载平衡、高性能、容错分解的分布式应用程序。 当多个可执行文件从同一队列读取时,这些队列允许进行负载平衡,并且内核调度程序只是将消息分发到空闲的进程。 Linux 的好处是可以在 Posix 队列上进行轮询,这有助于解决某些情况。 对于 IBM AIX,可以对 System V 队列进行轮询。

例如,两个进程可以通过队列轻松地进行本地通信,吞吐量相当可观(~70k req+rply/sec):

通过队列/性能发送和回复消息

如果需要联网,那么例如 Enduro/X 提供tpbridge 进程基本上从本地队列中读取消息,将块发送到其他机器,另一端将消息注入回本地队列。

此外,与套接字相比,您不会遇到任何队列问题,例如当某些二进制文件崩溃时,例如,程序在启动时可以立即开始读取队列并进行处理,从而导致繁忙/延迟套接字。

Message queues are very useful to build local decoupled applications. They are super fast, they are block organized (no need for buffering, cutting, etc which is the case for streaming sockets), basically few memcpy() operations (user code copy block to kernel, and kernel copy block to other process reading from q), and that's the story for message delivery. Some industry known middlewares such as Oracle Tuxedo or Mavimax Enduro/X uses these queues to help to build load balanced, high performance, fault tolerant decomposed, distributed applications. These queues allows to do load balancing, when several executables reads from the same queue, and kernel scheduler just distributes the message to processes which ever is idling. The nice thing for Linux is that poll can be done on Posix queues, which helps a to solve certain scenarios. For IBM AIX it is possible to do poll on System V queues.

For example, two processes can communicate easily locally over the queues with quite impressive throughput (~70k req+rply/sec):

Message sending and reply via queues / performance

If networking is needed, then for example Enduro/X provides tpbridge process which basically reads from messages from local queue, sends blocks to some other machine, where the other end injects the messages back in the local queue.

Also when comparing to sockets, you do not get any issues with queues, such as busy/lingering sockets when for example some binary have crashed, i.e. program at startup can immediately start to read the queues and do the processing.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文