我最近在Linux中一直在使用消息队列(系统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?
4 回答
是的,我认为消息队列适用于某些应用程序 . POSIX消息队列提供了一个更好的界面,特别是,您可以提供队列名称而不是ID,这对于故障诊断非常有用(可以更容易地查看哪个是哪个) .
Linux允许你将posix消息队列作为文件系统挂载并用“ls”查看它们,用“rm”删除它们也非常方便(系统V依赖于笨重的“ipcs”和“ipcrm”命令)
就个人而言,我非常喜欢消息队列,并认为它们可以说是unix世界中利用率最低的IPC . 它们快速且易于使用 .
几点想法:
其中一些只是时尚 . 旧事物再次成为新事物 . 在消息队列中添加一个闪亮的do-dad,它们可能是明年最新,最热门的东西 . 使用单独的进程而不是其选项卡的线程来查看Google的Chrome . 突然之间,人们很高兴当一个标签锁定时它不会导致整个浏览器崩溃 .
共享记忆有一些关于它的He-man光环 . 如果你没有从机器中挤出最后一个循环并且MQ的效率稍微低一些,那么你就不是一个“真正的”程序员 . 对于许多人而言,如果不是大多数应用程序,这完全是胡说八道,但有时候一旦 grab 它就很难打破心态 .
MQ实际上不适合具有无限数据的应用程序 . 管道或插座等面向流的机制更容易使用 .
System V变种确实已经失宠了 . 作为一般规则,尽可能使用POSIX版本的IPC .
POSIX消息队列的最大缺点:
POSIX消息队列不会使 requirement 与
select()
兼容 . (它适用于Linux中的select()
但不适用于Qnx系统)它有惊喜 .
Unix数据报套接字执行与POSIX消息队列相同的任务 . Unix数据报套接字在套接字层工作 . 可以将它与
select()
/poll()
或其他IO等待方法一起使用 . 在设计基于事件的系统时,使用select()
/poll()
具有优势 . 以这种方式可以避免繁忙的循环 .消息队列中有惊喜 . 想想
mq_notify()
. 它用于获取接收事件 . 听起来我们可以通知一些有关消息队列的信息 . 但它实际上是在注册通知而不是通知任何内容 .关于
mq_notify()
的更多惊喜是它必须在每个mq_receive()
之后被调用,这可能会导致竞争条件(当一些其他进程/线程在mq_receive()
和mq_notify()
的调用之间调用mq_send()
时) .它有一整套
mq_open, mq_send(), mq_receive() and mq_close()
,它们有自己的定义,这是冗余的,在某些情况下与socketopen(),send(),recv() and close()
方法规范不一致 .我不认为消息队列应该用于同步 .
eventfd
和signalfd
适用于此 .但是 it(POSIX message queue) has some realtime support . 它具有优先功能 .
但是这个优先级也可用作套接字作为带外数据!
最后,对我来说,POSIX消息队列是一个遗留API . 只要不需要实时功能,我总是更喜欢Unix数据报套接字而不是POSIX消息队列 .
我实际上并没有使用POSIX消息队列,因为我总是希望保持打开选项以通过网络分发我的消息 . 考虑到这一点,您可能会看到一个更强大的消息传递接口,如zeromq或实现AMQP的东西 .
关于0mq的一个好处是,当从一个相同的进程空间使用时多线程应用程序,它使用非常快的无锁零拷贝机制 . 不过,您仍然可以使用相同的界面通过网络传递消息 .