使用POSIX消息队列而不是TCP套接字 - 如何建立“连接”?

问题描述:

我有客户端和服务器程序,现在通过TCP进行通信。我尝试使用POSIX消息队列(当然客户端和服务器在同一台机器上)。我希望它能够提高性能(特别是通过减少延迟)。使用POSIX消息队列而不是TCP套接字 - 如何建立“连接”?

我已经完成了大部分工作,但我不确定一件事:如何建立“连接”。服务器接受来自多个客户端同时连接,所以我很想效仿TCP连接建立过程中,像这样:

  1. 服务器不断地打开一个队列,一个众所周知的名称和读取(它可以使用select(2)与TCP一样)。
  2. 客户端打开三个队列:两个具有任意名称(包括某些唯一性,如PID以避免冲突),另一个具有服务器使用的已知名称。
  3. 客户端向服务器队列发送“连接”消息,包括客户端的队列名称(一个用于客户端到服务器的流量,另一个用于反向)。
  4. 服务器将打开客户端连接消息中指定的队列,并开始从客户端到服务器端读取(选择)一个队列。
  5. 客户端使用众所周知的名称关闭服务器队列。双向通信使用客户端命名的两个队列(每个方向一个队列)进行。

你或许可以看到这个方案如何与普通的TCP方法相似,这并非偶然。但是,我想知道:

  1. 您能想到更好的方法吗?
  2. 您是否看到我的方法有任何潜在的问题?
  3. 您是否还有其他想法,包括在同一台计算机上使用消息队列而不是TCP实际上会提高性能(延迟)的可能性?

请记住,我之前没有使用过POSIX消息队列(我之前使用过IBM WebSphere MQ,但是这有点不同)。该平台是Linux。

我结束了如I中所述基本上实现它,有一些改进:

  • 在步骤2中,我使用的GUID队列名称,而不是结合在客户端的PID 。
  • 在步骤4中,我添加了从服务器到客户端的“接受”消息的发送。
  • 当任何一方希望结束通信时,它会发送一个“断开”消息。

握手比TCP简单,但似乎足够。

至于等待时间:好多了。在同一台计算机上使用POSIX消息队列而不是TCP大约可减少75%的延迟。我的消息每个都是100字节。

  1. 你能想出更好的办法来做到这一点?

    也许看看fifos(又名命名管道)。它们就像网络套接字,但是用于本地机器。它们是单向的,因此您可能需要为每个方向创建两个,一个。你的问题确实没有任何理由为什么你正在做这个改变。使用套接字进程处理通信没有任何问题。它们是双向的,高效的,受到广泛支持,并且可以让您*地将机器之间的过程分开。

  2. 您是否看到我的方法有任何潜在的问题?

    系统V消息队列和FIFO命名管道都非常好。 Fifo管道就像常规管道,所以你可以用最少的代码改变来读取()和写入()。System V消息队列需要将数据放入结构中并调用msgsnd()。但是,任何一种方法都可以。

  3. 您是否有其他想法,包括在同一台计算机上使用消息队列而不是TCP实际上会提高性能(延迟)的可能性?

    我的其他想法是,如你所说,你需要开发一种技术,以便每个客户端都有一个唯一的标识符。一种方法是将pid添加到您传递的结构中,或者在开始时与父/母协商一个唯一标识。另外需要注意的是,System V消息队列的好处是您可以侦听“选择性”消息,因此您可以理想地使用从服务器到所有客户端的一个队列,并且每个客户端都在等待不同的消息。

    我不知道哪种技术可以为您提供软件中最佳的吞吐量。实际上可能不值得使用System V消息队列,但只有您可以做出该决定。

Philluminati

+0

你说我的“问题没有任何理由说明你为什么要做这个改变。”我确实提到它:性能(延迟)。 System V消息队列与POSIX的功能不同吗?我使用的POSIX(例如mq_open(3))似乎不支持您提到的“选择性”消息。 – 2009-01-04 03:59:47

+0

我现在尝试使用命名管道。它们比POSIX消息队列更慢(至少传递大量小消息)。 – 2009-01-05 16:41:56

当select()对消息队列不起作用时,你是如何做到的?什么是Sys V或POSIX? 当PID保证唯一且较小的存储空间(整数)时,为什么需要额外的努力来创建GUID到PID查找表?

/blee/

+0

这应该是对我的答案的评论。无论如何: 选择使用POSIX消息队列,这是我使用的。 PID查找表没有GUID - GUID在进程之间通信,PID从不使用。 PID不是唯一的 - 它们在大多数系统上都可以回收利用。 – 2009-02-17 23:29:55

我见过类似的问题,我开发实时应用程序,需要IPC技术与类似插座的功能和最小的延迟。

您是否将基于POSIX-MQ的解决方案与UNIX本地套接字或TCP套接字进行了比较?

由于

我比较POSIX MQ的性能和一对TCP/IP套接字的。

演示程序有两个线程,一个用于写入,另一个用于读取。

结果是POSIX MQ更快,

  • MQ 460000 TPS
  • socketpair 400000个TPS

您还可以在驻留在不同机器上的程序使用消息队列的IPC,在这种情况下,您可以使用ZeroMQ(http://www.zeromq.org)或其他消息队列API,我还建议您考虑它们并进行测试。