IPC的性能:命名pipe道与套接字

每个人似乎都认为命名pipe道比套接字IPC更快。 他们快多less? 我更喜欢使用套接字,因为它们可以进行双向通信,而且非常灵活,但是如果数量相当多的话,它会select速度而不是灵活性。

我建议你先走容易的路径,仔细隔离的ipc机制,以便您可以更改从套接字到管道,但我肯定会先用套接字。 在抢先优化之前,您应该确定IPC性能是一个问题。

如果由于IPC速度而陷入困境,我认为你应该考虑切换到共享内存而不是去管道。

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

我会同意shodanex,看起来你过早地试图优化一些尚未解决的问题。 除非你知道套接字将成为一个瓶颈,我只是用它们。

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

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

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

请记住,套接字不一定意味着IP(和TCP或UDP)。 您还可以使用UNIX套接字(PF_UNIX),与连接到127.0.0.1相比,可以显着提高性能

通常情况下,数字不仅仅是感觉,下面是一些数据: Pipe vs Unix Socket Performance(opendmx.net) 。

这个基准测试显示,管道的速度提高大约12到15%。

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

  • 如果你有几个进程,你可以打开两个管道(processA2ProcessB和processB2ProcessA)
  • 如果你有很多进程,你可以为每个进程打开和关闭管道(processAin,processAout,processBin,processBout,processCin,processCout等)
  • 或者你可以像往常一样去混合:)

命名管道很容易实现。

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

我甚至用java编码(我正在序列化和发送对象!)

命名管道有一个缺点:

  • 它们并不像套接字那样在多台计算机上扩展,因为它们依赖于文件系统(假设共享文件系统不是一个选项)

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

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

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

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

Unix域套接字几乎可以完成tcp套接字的工作,但是只能在本地机器上进行,而且可能会花费更少的开销。

如果一个Unix套接字不够快,而且你正在传输大量的数据,那么考虑在你的客户端和服务器之间使用共享内存(这是很复杂的)。

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

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

您可以使用套接字选项TCP_NODELAY来禁用Nagle,但是读取结束将永远不会在一次读取调用中收到两条短消息。

所以测试一下,我没有结束这一切,并在共享内存中使用pthread互斥体和信号量实现了基于内存映射的队列,避免了很多内核系统调用(但是现在它们不再是很慢)。

您可以使用像ZeroMQ [ zmq / 0mq ]这样的轻量级解决方案。 这是非常容易使用和显着更快的插座。