IPC的性能:命名pipe与套接字
每个人似乎都认为命名pipe道比套接字IPC更快。 他们快多less? 我更喜欢使用套接字,因为它们可以进行双向通信,而且非常灵活,但是如果数量相当多的话,它会select速度而不是灵活性。
我build议你先走容易的path,仔细隔离的ipc机制,以便您可以更改从套接字到pipe道,但我肯定会先用套接字。 在抢先优化之前,您应该确定IPC性能是一个问题。
如果由于IPC速度而陷入困境,我认为你应该考虑切换到共享内存而不是去pipe道。
如果你想做一些传输速度testing,你应该尝试socat ,这是一个非常通用的程序,可以让你创build几乎任何types的隧道。
我会同意shodanex,看起来你过早地尝试优化一些尚未解决的问题。 除非你知道套接字将成为一个瓶颈,我只是用它们。
很多通过命名pipe道发誓的人find了一点积蓄(取决于其他所有东西的写法),但是最终得到的代码会花费更多的时间来阻止IPC回复,而不是做有用的工作。 当然,非阻塞的scheme可以帮助解决这个问题,但这些可能会非常棘手。 花费多年的时间,将旧的代码带入现代,我可以说,在我见过的大多数情况下,加速几乎为零。
如果你真的认为套接字会让你放慢速度,那么请使用共享内存走出门外,小心使用锁。 再一次,在所有的现实中,你可能会发现一个小的加速,但是注意到你正在浪费一部分等待互斥锁。 我不会主张去futex地狱 (好吧,到2015年,根据你的经验,不再是地狱了)。
英镑磅,套接字(几乎)总是最好的方式去用户空间IPC单核内核..和(通常)最容易debugging和维护。
请记住,套接字不一定意味着IP(和TCP或UDP)。 您还可以使用UNIX套接字(PF_UNIX),与连接到127.0.0.1相比,可以显着提高性能
通常情况下,数字不仅仅是感觉,下面是一些数据: Pipe vs Unix Socket Performance(opendmx.net) 。
这个基准testing显示,pipe道的速度快了12%到15%。
对于与命名pipe道的双向通信:
- 如果你有几个进程,你可以打开两个pipe道(processA2ProcessB和processB2ProcessA)
- 如果你有很多进程,你可以为每个进程打开和closurespipe道(processAin,processAout,processBin,processBout,processCin,processCout等)
- 或者你可以像往常一样去混合:)
命名pipe道很容易实现。
例如,我使用命名pipe道在C中实现了一个项目,这要归功于基于标准文件input – 输出的通信(fopen,fprintf,fscanf …),它非常简单和干净(如果这也是一个考虑因素)。
我甚至用java编码(我正在序列化并通过它们发送对象!)
命名pipe道有一个缺点:
- 它们并不像套接字那样在多台计算机上扩展,因为它们依赖于文件系统(假设共享文件系统不是一个选项)
如果你不需要速度,套接字是最简单的方法去!
如果你正在看的是速度,最快的解决scheme是共享内存,而不是命名pipe道。
命名pipe道和套接字在function上并不相同; 套接字提供更多的function(它们是双向的,一开始)。
我们不能告诉你哪个performance会更好,但我强烈怀疑这并不重要。
Unix域套接字几乎可以完成tcp套接字的工作,但是只能在本地机器上进行,而且可能会花费更less的开销。
如果一个Unix套接字不够快,而且你正在传输大量的数据,那么考虑在你的客户机和服务器之间使用共享内存(这个设置比较复杂)。
Unix和NT都有“命名pipe道”,但是它们在function上完全不同。
套接字的一个问题是,他们没有办法冲洗缓冲区。 有一种叫做Naglealgorithm,收集所有数据并在40ms后刷新它。 所以如果它是响应而不是带宽你可能会更好用pipe道。
您可以使用套接字选项TCP_NODELAY来禁用Nagle,但是读取结束将永远不会在一次读取调用中收到两条短消息。
所以testing一下,我没有结束这一切,并在共享内存中使用pthread互斥体和信号量实现了基于内存映射的队列,避免了大量内核系统调用(但是现在它们不再是很慢)。
您可以使用像ZeroMQ [ zmq / 0mq ]这样的轻量级解决scheme。 这是非常容易使用和显着更快的sockets。