Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/opencv/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 对于本地IPC、POSIX消息队列(MQUEUE)或Unix域(本地)套接字,哪个更好?_C++_C_Sockets_Ipc_Posix - Fatal编程技术网

C++ 对于本地IPC、POSIX消息队列(MQUEUE)或Unix域(本地)套接字,哪个更好?

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域套接字 是一个比另一个好,还是编程熟悉的问题?或

使用POSIX消息队列或Unix域套接字进行本地IPC通信是否更好

我曾经使用过机器(而不是域)之间的Unix套接字,我记得建立和断开连接会导致套接字在最终消失之前停留一段时间。此外,如果您想要一个“可靠”的交换,您必须使用TCP或设计应用程序以返回ACK。但我不确定这是否也适用于Unix域套接字

在我目前的项目中,我们需要本地IPC。我的第一反应是使用POSIXMQUES,因为我以前在本地消息传递中使用过它们。然而,一位同事建议改为使用Unix域套接字

是一个比另一个好,还是编程熟悉的问题?或者它取决于正在创建的应用程序

总体来说,我们正在开发的应用程序遵循客户机/服务器模式。客户端向服务器发送消息以“执行某些操作”。然而,客户机并不等待“its done”响应——尽管他们确实想知道他们的请求是否已收到

发送端的基本逻辑是:

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实时扩展保持一致。”