【问题标题】:Communication between processes进程之间的通信
【发布时间】:2011-01-02 21:49:14
【问题描述】:

我正在寻找一些数据来帮助我决定哪个对于 Linux 上两个独立进程之间的通信更好/更快:

  • TCP
  • 命名管道

哪个更糟:管道的系统开销或 tcp 堆栈开销?


更新的确切要求:

  • 只需要本地 IPC
  • 主要是很多短信
  • 不需要跨平台,只需要 Linux

【问题讨论】:

  • 我不认为,它需要一个单独的答案,但在我看来,如果您在同一台机器上的不同进程之间进行通信,则绝对没有理由使用 TCP i>(嗯,很明显)。当然,除非我遗漏了一些重要的东西。
  • 好吧,TCP 的优势在于,如果有必要的话,分离应用程序是微不足道的。未来的投资,如果你愿意的话。除此之外,我当然同意你的看法。
  • 哦,要指出我的短视 :) 卡尔·斯莫特里兹(Carl Smotricz),这当然是一个非常有效的观点!
  • 我可以建议您将您的要求添加到问题中吗?即跨平台/性能。我已经根据收集到的 cmets 更新了我的答案。

标签: c++ linux


【解决方案1】:

在过去,我使用本地域套接字来处理这类事情。我的库确定其他进程是系统本地的还是远程的,并使用 TCP/IP 进行远程通信,使用本地域套接字进行本地通信。这种技术的好处是本地/远程连接对应用程序的其余部分是透明的。

本地域套接字使用与管道相同的机制进行通信,并且没有 TCP/IP 堆栈开销。

【讨论】:

  • 您有更多相关信息吗?任何链接?你用的是哪个库?
  • 抱歉,这是我自己为雇主编写的库。我无法提供链接。
  • 啊,我明白了。我将看看域套接字,这些听起来很有趣。谢谢!
  • 根据维基百科,Unix Domain Sockets 的正确名称是 POSIX Local IPC Sockets。
【解决方案2】:

我真的不认为你应该担心开销(这会低得离谱)。您是否确保使用分析工具时应用程序的瓶颈可能是 TCP 开销?

无论如何,正如 Carl Smotricz 所说,我会使用套接字,因为将来分离应用程序真的很简单。

【讨论】:

  • +1:过去我们使用共享内存(目前使用 boost.interprocess 来实现),但最终它的麻烦多于它的价值。套接字 / TCP 的开销在环回上肯定非常低,因此真的不值得担心。当然,请确定您的特定用例。
【解决方案3】:

我在回复previous post 时讨论了这个问题。我不得不比较套接字、管道和共享内存通信。管道绝对比套接字快(如果我没记错的话,可能是 2 倍……当我回去工作时,我可以检查这些数字)。但这些测量只是为了纯粹的交流。如果沟通只是整体工作的一小部分,那么这两种沟通方式之间的差异可以忽略不计。

编辑 以下是我几年前进行的测试中的一些数字。您的里程可能会有所不同(特别是如果我犯了愚蠢的编程错误)。在这个特定的测试中,同一台机器上的“客户端”和“服务器”来回回显 100 字节的数据。它提出了 10,000 个请求。在我写的文件中,我没有说明机器的规格,所以只有相对速度可能有任何价值。但出于好奇,这里给出的时间是每个请求的平均成本:

  • TCP/IP:.067 ms
  • 带有 I/O 完成端口的管道:.042 ms
  • 具有重叠 I/O 的管道:.033 ms
  • 与命名信号量共享内存:.011 ms

【讨论】:

  • 我正在寻找极其快速的短消息通信,它控制我的程序流程(即程序在每次迭代后询问是否可以继续)
  • 如果您使用 TCP/IP,请务必关闭 Nagle 算法。
  • 对于短消息(特别是如果有大量消息),管道可能会更快。如果你想要额外的痛苦,你可以通过使用简单的共享内存来获得更快的速度。当我开始工作并在此处提供它们时,我会尽量记住获取管道与 tcp/ip 编号。正如我在另一篇文章中提到的那样,那是几年前的事了,但我怀疑现在的相对速度会相似。
【解决方案4】:

使用 TCP 会有更多开销 - 这将涉及将数据分解为数据包、计算校验和和处理确认,在同一台机器上的两个进程之间进行通信时,这些都不是必需的。使用管道只会将数据复制到缓冲区中或从缓冲区中复制出来。

【讨论】:

  • 开销真的那么大吗?
  • 如果处理器只有 100MHZ(我经常工作的地方),那么开销会大得多。如果您在 GHZ 范围内并且不关心顶级性能,那么这可能不值得麻烦。
  • 并不是说开销那么多——127.0.0.1 的 MTU 通常非常大,所以它不必将它分成那么多数据包——但它仍然需要更多步骤比命名管道。更重要的问题是:您是否希望这种通信在不同的计算机之间进行?如果是这样,那么使用套接字,因为命名管道根本无法在不同的机器之间工作。还有 UNIX 域套接字,它们在像套接字一样工作时可以像管道一样执行。最后,命名管道的另一个优点是访问控制和命名空间(路径与 IP/端口)。
  • 是的,我们已经使用套接字进行机器之间的通信,我正在寻找本地管理进程和工作程序之间的通信。
  • 我同意 unix 域套接字(见我的回答)。它们在 POSIX 中称为本地域套接字。
【解决方案5】:

我不知道这是否适合你,但在 linux 下,一种非常常见的 IPC(进程间通信)方式是使用共享内存。它实际上是超快的(我没有对此进行分析,但这只是 RAM 上的共享数据,具有强大的处理能力)。

这个方法的主要问题是信号量,你必须围绕它构建一个小系统,所以你必须确保一个进程不会在另一个进程试图读取的同时写入。

一个非常简单的入门教程在here

这不像使用套接字那样可移植,但概念是相同的,因此如果您要将其迁移到 Windows,您只需更改共享内存创建/附加层。

【讨论】:

  • +1:我在 MS Windows 中为 IPC 使用共享内存已经有一段时间了。它工作得很好;您唯一需要注意的是共享内存是一种固定大小的数组;所以你必须有一种机制来同步不同进程对它的访问。
  • 只是另一条评论,在 Windows 下,您可以在 MSDN 上搜索 CreateFileMapping/OpenFileMapping 和 MapViewOfFile
【解决方案6】:

需要考虑的两件事:

  1. 连接设置费用
  2. 持续通信成本

在 TCP 上:

(1) 成本更高 - (可能)不可靠的通道需要 3 次握手开销。

(2) 成本更高 - IP 级开销(校验和等)、TCP 开销(序列号、确认、校验和等)几乎所有这些都不需要在同一台机器上,因为通道应该是可靠且不会引入与网络相关的损伤(例如数据包重新排序)。

但我仍然会使用 TCP 只要它有意义(即取决于具体情况),因为它无处不在(阅读:简单的跨平台支持)并且开销应该不是问题在大多数情况下(阅读:配置文件,不要过早优化)。

更新:如果不需要跨平台支持并且重点是性能,那么请使用 命名/域管道,因为我很确定平台开发人员将优化处理网络级损伤所需的不必要功能。

【讨论】:

  • 我明白:那么命名管道在性能方面肯定会降低成本。
【解决方案7】:

unix domain socket 是一个非常好的妥协。不是 tcp 的开销,而是比管道解决方案更具发展性。您没有考虑的一点是套接字是双向的,而命名管道是单向的。

【讨论】:

    【解决方案8】:

    我认为管道会更轻一些,但我只是猜测。

    但由于管道是本地的东西,可能涉及的代码要简单得多。

    其他人可能会告诉您尝试测量两者以找出答案。这个答案很难出错,但你可能不愿意花时间。那会让你希望我的猜测是正确的;)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-09-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-05
      • 2011-08-03
      • 1970-01-01
      相关资源
      最近更新 更多