2009-08-05 129 views
70

大家似乎认为命名管道比套接字IPC更快。他们有多快?我更喜欢使用套接字,因为它们可以进行双向通信,而且非常灵活,但是如果数量相当大,它会选择速度而不是灵活性。IPC的性能:命名管道VS套接字

+10

您的里程将有所不同。 :)描述您的预期应用的典型用途,并选择两者中较好的一个。然后配置匿名管道,其他领域和家庭的套接字,信号量和共享内存或消息队列(SysV和POSIX),带有数据字的实时信号或任何其他信息。 '管(2)'(呃,'mkfifo(3)'?)可能是胜利者,但直到你尝试才会知道。 – pilcrow 2009-08-06 01:31:40

+2

SysV消息队列FTW!我不知道他们是否快速,我只是对他们有一个情有独钟。 – 2010-09-21 17:44:35

+2

这种情况下的“速度”是什么?总体数据传输率?或延迟(第一个字节到达接收器的速度有多快)?如果你想快速的本地数据传输,那么很难击败共享内存。如果延迟是一个问题,那么问题会变得更有趣...... – 2016-03-30 20:28:52

回答

4

命名管道和套接字在功能上并不等同;套接字提供更多功能(它们是双向的,用于开始)。

我们不能告诉你哪个表现会更好,但我强烈怀疑这并不重要。

Unix域套接字将完成tcp套接字的功能,但只能在本地计算机上执行,并且(可能有点)开销较低。

如果Unix套接字速度不够快并且传输大量数据,请考虑在客户端和服务器之间使用共享内存(这是很复杂的设置)。

Unix和NT都有“命名管道”,但它们在功能集中完全不同。

+1

那么,如果你打开2管道,那么你也得到比迪的行为。 – Pacerier 2017-02-19 21:13:24

46

我建议你采用最简单的第一个,仔细分离IPC机制,这样就可以从插座改为管,但我肯定会带插座先走了。 在抢先优化之前,您应该确定IPC性能是一个问题。

而且,如果您因为IPC速度的麻烦,我想你应该考虑切换到共享内存而不是去管。

如果你想做一些传输速度测试,你应该尝试socat,这是一个非常通用的程序,允许你创建几乎任何类型的隧道。

+2

+1为socat,在 – galaktor 2014-01-15 08:43:55

+1

@shodanex之前没有看到过,“共享内存”是指你的意思是线程还是..? – Pacerier 2017-02-19 21:09:09

25

我会用shodanex同意,它看起来像你过早地想优化的东西是没有问题的。除非你知道套接字将成为瓶颈,我只是使用它们。

很多通过命名管道发誓的人找到了一点积蓄(取决于其他所有东西的写入情况),但最终得到的代码与IPC做的有用工作相比,花在IPC回复上的时间更多。当然,非阻塞方案有助于这一点,但这些可能会非常棘手。花费数年时间,将旧代码带入现代,我可以说,在我见过的大多数情况下,加速几乎为零。

如果你真的认为套接字会让你放慢速度,那么请使用共享内存走出门外,仔细注意你如何使用锁。再一次,在所有的现实中,你可能会发现一个小的加速,但是注意到你正在浪费一部分等待互斥锁。我不打算主张去futex hell(很好,不是相当于地狱在2015年,这取决于你的经验)。

英镑磅,插座(几乎)总是最好的方式去用户空间IPC下单片内核..和(通常)最容易调试和维护。

6

如果你不需要速度,套接字是最简单的方法!

如果你正在寻找的是速度,最快的解决方案是共享内存,而不是命名管道。

7

对于双向通信与命名管道:

  • 如果你有几道工序,就可以打开两个管道的两个方向(processA2ProcessB和processB2ProcessA)
  • 如果你有很多过程,你可以打开并出于对每一个工艺管道(processAin,processAout,processBin,processBout,processCin,processCout等)
  • 或者你可以去混合一如既往:)

南ed管道很容易实现。

E.g.我使用命名管道在C中实现了一个项目,这要归功于基于标准文件输入输出的通信(fopen,fprintf,fscanf ...),它非常简单和清晰(如果这也是一个考虑因素)。

我甚至用java编码他们(我被序列化,并在他们发送的对象!)

命名管道有一个缺点:

  • ,因为他们依靠他们不扩大在多台计算机就像插座文件系统(假设共享文件系统不是一个选项)
20

请记住,套接字不一定意味着IP(以及TCP或UDP)。您还可以使用Unix套接字(PF_UNIX),它提供了一个显着的性能改进了连接到127.0.0.1

+1

Windows怎么样? – Pacerier 2017-02-19 21:10:11

+1

@Place不幸的是,你不能像在UNIX上的抽象名字空间一样在Windows上创建本地套接字。我发现PF_​​UNIX套接字比本页介绍的大多数其他方法快得多(> 10%)。 – EntangledLoops 2017-04-14 15:04:05

4

套接字的一个问题是它们没有办法刷新缓冲区。有一种叫做Nagle算法,收集所有数据并在40ms后刷新它。因此,如果它是响应性而不是带宽,那么使用管道可能会更好。

您可以使用套接字选项TCP_NODELAY禁用Nagle,但读取结束将永远不会在一次读取调用中收到两条短消息。所以测试一下,我没有得到这个结果,并且在共享内存中使用pthread互斥体和信号量实现了基于内存映射的队列,避免了很多内核系统调用(但是现在它们不再很慢)。

+1

“所以测试它”< - 生活的话。 – Koshinae 2016-04-18 09:03:25

1

您可以使用像ZeroMQ [zmq/0mq]这样的轻量级解决方案。它使用起来非常简单,而且插座的速度要快得多。

+1

您可能会喜欢,猜猜Amit,Martin SUSTRIK的下一个作品 - POSIX兼容**'nanomsg' **。无论如何,欢迎和享受这个伟大的地方,并成为它的积极贡献会员。 – user3666197 2017-04-02 06:06:59

+0

肯定会尝试,谢谢。 – 2017-04-02 13:05:23