C++ 对于本地IPC、POSIX消息队列(MQUEUE)或Unix域(本地)套接字,哪个更好?
使用POSIX消息队列或Unix域套接字进行本地IPC通信是否更好 我曾经使用过机器(而不是域)之间的Unix套接字,我记得建立和断开连接会导致套接字在最终消失之前停留一段时间。此外,如果您想要一个“可靠”的交换,您必须使用TCP或设计应用程序以返回ACK。但我不确定这是否也适用于Unix域套接字 在我目前的项目中,我们需要本地IPC。我的第一反应是使用POSIXMQUES,因为我以前在本地消息传递中使用过它们。然而,一位同事建议改为使用Unix域套接字 是一个比另一个好,还是编程熟悉的问题?或者它取决于正在创建的应用程序 总体来说,我们正在开发的应用程序遵循客户机/服务器模式。客户端向服务器发送消息以“执行某些操作”。然而,客户机并不等待“its done”响应——尽管他们确实想知道他们的请求是否已收到 发送端的基本逻辑是:C++ 对于本地IPC、POSIX消息队列(MQUEUE)或Unix域(本地)套接字,哪个更好?,c++,c,sockets,ipc,posix,C++,C,Sockets,Ipc,Posix,使用POSIX消息队列或Unix域套接字进行本地IPC通信是否更好 我曾经使用过机器(而不是域)之间的Unix套接字,我记得建立和断开连接会导致套接字在最终消失之前停留一段时间。此外,如果您想要一个“可靠”的交换,您必须使用TCP或设计应用程序以返回ACK。但我不确定这是否也适用于Unix域套接字 在我目前的项目中,我们需要本地IPC。我的第一反应是使用POSIXMQUES,因为我以前在本地消息传递中使用过它们。然而,一位同事建议改为使用Unix域套接字 是一个比另一个好,还是编程熟悉的问题?或
connect to server
send request
note if the send worked or not
disconnect from server
一台服务器可以有数百个客户端
我们正在运行Linux操作系统的SMP系统(4-8核)上执行
提前感谢。UNIX域套接字不必以类似于
等待时间的状态“逗留”,因为该等待时间用于防止来自连接的散乱数据包仍然在Internet上徘徊。这种担心在当地并不适用
UNIX域套接字可以是SOCK_-STREAM
(如TCP)或SOCK_-DGRAM
(如UDP),还可以保证UNIX域数据报套接字是可靠的,并且不会对数据报重新排序
如果您想确定您的其他应用程序已经阅读了您发送的消息,您仍然需要某种形式的确认(即使使用TCP也需要);毕竟,即使send()
成功,它也可能在有机会处理消息之前就崩溃了。(这也适用于消息队列-为了完全确保消息不会丢失,接收应用程序必须将请求写入日志,将其刷新到磁盘,然后发送回确认)
我同意,选择基本上是编程熟悉度的问题
是一个比另一个好,还是编程熟悉的问题?或者它取决于正在创建的应用程序
SysV消息队列与UNIX域数据报套接字相比有以下主要区别:
- 您可以
poll()
socket,但不能使用消息队列
- 消息队列是全局的,可能(而且通常)需要一些管理参与:清理旧的挂起的SysV资源是许多sysadmin日常例程之一。虽然UNIX域的语义要简单得多,应用程序通常可以完全在内部维护它,而无需系统管理员的参与
- (?)消息队列是持久的,它可能会保留来自旧会话的消息。(我记不清那一点了,但IIRC不止一次发生在我身上)
- 查看
man msgrcv
我没有看到插座的MSG_PEEK
类似物。很少需要,但有时很方便
- 大多数情况下,用户更喜欢在配置中使用符号名,而不是数字键id。缺少符号键IMO是SysV接口设计者的一个严重疏忽
与所有SysV资源一样,它们的管理是主要的PITA。若您让系统决定消息队列ID,那个么您必须注意与其他应用程序正确共享它。(您还必须以某种方式告诉管理员,最终必须删除ID)。如果允许为消息队列配置密钥,则可能会遇到一些小问题,即该id已被某些应用程序使用,或者是上一次运行的剩余id。(看到服务器重新启动只是因为它们耗尽了SysV资源是很常见的。)
总而言之,我尽可能避免使用SysV资源:在最常见的情况下,缺少poll()
支持会破坏交易
然而,客户机并不等待“its done”响应——尽管他们确实想知道他们的请求是否已收到
这是事务处理的常见难题。一般的响应是(在RDBMS中)您不能,在通信中断(崩溃或其他情况)后,应用程序必须检查自己是否已经处理了请求
从这一点我可以看出,TCP可能是一个更好的选择。客户机发送请求,并仅当从服务器获得肯定响应时才将其声明为已完成。除非服务器能够向客户机发送响应,否则它必须回滚事务。我建议为这样的应用程序查看DBU,哪怕只是为了它们的数据编组和类似RPC的接口(同步和异步)。它本机使用域套接字,在初始学习曲线之后工作得非常好。不过,在Linux上,posix消息队列描述符实际上是一个文件描述符,它支持select/poll。我不确定sysv消息队列。@nos:reference?您不是在将它与AIX混合使用吗?POSIX没有描述这一点,并且还说no.man mq_overview,“在Linux上,消息队列描述符实际上是一个文件描述符,可以使用select(2)、poll(2)或epoll(7)进行监视。这是不可移植的。”,正如前面提到的,这是POSIX消息队列,我不确定sysv消息队列是否以这种方式工作,如果他们这么做了,这几年就改变了。@No:谢谢。这就解释了为什么有两个接口。mq.*
函数是:“在第5期中首次发布。包括用于与POSIX实时扩展保持一致。”