哪个更适合本地IPC,POSIX消息队列(mqueues)或Unix域(本地)套接字?

Joh*_*cha 22 c c++ sockets posix ipc

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

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

在我目前的项目中,我们需要本地IPC.我的第一反应是使用POSIX MQueues,因为我之前使用它们进行本地消息传递.但是,一位同事正在建议使用Unix域套接字.

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

从总体上看,我们正在开发的应用程序遵循客户端/服务器模型.客户端向服务器发送消息以"做某事".但是,客户端不会等待"完成"响应 - 尽管他们确实想知道他们的请求是否已被接收.

发送方的基本逻辑是:

connect to server
send request
note if the send worked or not
disconnect from server
Run Code Online (Sandbox Code Playgroud)

一台服务器可能有数百个客户端.

我们正在运行Linux操作系统的SMP系统(4-8个核心)上执行.

提前致谢.

Dum*_*001 6

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

与 UNIX 域数据报套接字相比,SysV 消息队列具有我所知道的主要区别:

  • 您可以使用poll()套接字,但不能使用消息队列。

  • 消息队列是全局的,可能(通常确实)需要一些管理参与:清理旧的挂起的 SysV 资源是许多系统管理员日常工作之一。虽然 UNIX 域的语义要简单得多,而且应用程序通常可以完全在内部维护它,而无需系统管理员参与。

  • (?) 消息队列是持久的,它可能会保留来自旧会话的消息。(无法准确地回忆起那一点,但是 IIRC 不止一次发生在我身上)。

  • 看着man msgrcv我没有看到 socket 的模拟MSG_PEEK。很少需要,但有时会很方便。

  • 大多数时候,用户更喜欢在配置中使用符号名称,而不是数字键 id。缺少符号键 IMO 是部分 SysV 界面设计者的严重疏忽。

与所有 SysV 资源一样,它们的管理是主要的 PITA。如果您让系统决定消息队列 ID,那么您必须注意与其他应用程序正确共享它。(并且您还必须以某种方式告诉管理员该 ID 最终必须被删除)。如果您允许为消息队列配置密钥,那么您可能会遇到一些小问题,即该 ID 已被某些应用程序使用,或者它是上次运行的残余。(看到服务器仅因为 SysV 资源耗尽而重新启动是很常见的。)

总而言之,我尽可能避免使用 SysV 资源:poll()在大多数常见情况下缺乏支持是一个交易破坏者。

但是,客户端不会等待“完成”响应——尽管他们确实想知道他们的请求是否已收到。

这是事务处理的常见困境。一般响应是(如在 RDBMS 中)您不能,并且在通信中断(崩溃或其他)之后,应用程序必须自行检查请求是否已被处理。

由此我可以看出 TCP 可能是更好的选择。客户端发送请求并只有在得到服务器的肯定响应时才声明它已完成。服务器除非能够向客户端发送响应,否则必须回滚事务。

  • man mq_overview, "在 Linux 上,消息队列描述符实际上是一个文件描述符,可以使用 select(2)、poll(2) 或 epoll(7) 进行监视。这不可移植。" ,正如前面提到的,这是 posix 消息队列,我不确定 sysv 消息队列是否以这种方式工作,如果他们这样做了,近年来已经发生了变化。 (4认同)
  • 不过,在 Linux 上,posix 消息队列描述符实际上是一个文件描述符,它支持选择/轮询。我不确定 sysv 消息队列。 (2认同)

caf*_*caf 5

UNIX域套接字不必以类似TIME_WAIT状态" 延迟" ,因为如果来自连接的杂散数据包仍然在Internet上闲逛,则使用该等待时间.该问题不适用于当地.

UNIX域套接字可以是SOCK_STREAM(如TCP)或SOCK_DGRAM(如UDP),还可以保证UNIX域数据报套接字是可靠的,不会重新排序数据报.

如果你想确定你的其他应用程序已经阅读了你发送的消息,你仍然需要某种ACK(你甚至使用TCP); 毕竟,即使send()成功,它也可能在它有机会处理消息之前崩溃.(这也适用于消息队列 - 完全确定消息不会丢失,接收应用程序必须将请求写入日志,将其刷新到磁盘然后发回确认).

我同意这个选择基本上是编程熟悉的问题.