在Linux上,C ++应用程序进程之间发送消息的最快技术是什么? 我隐约地意识到以下技术在桌面上:
有没有更多的方法,什么是最快的?
我也建议看看这个: 如何在C中使用与Linux共享内存 。
基本上,当在一台机器上进行IPC时,我会放弃TCP和UDP等网络协议。 这些打包开销和绑定到更多的资源(如端口,环回接口)。
虽然所有上述答案都非常好,但我认为我们必须讨论什么是“最快”(而且必须是“最快”还是“足够快”)?
对于大型消息来说,共享内存毫无疑问是一个非常好的技术,在很多方面都非常有用。
但是,如果消息很小,则不得不提出自己的消息传递协议和通知另一个进程有消息的方法。
在这种情况下,管道和命名管道的使用要容易得多 – 它们的行为非常类似于文件,只需在发送端写入数据,然后在接收端读取数据即可。 如果发件人写东西,接收方会自动唤醒。 如果管道已满,则发送方将被阻塞。 如果发件人没有更多的数据,则接收方自动被阻止。 这意味着,这可以用相当少的几行代码来实现,而且每次都能在任何时候都能正常工作。
另一方面,共享内存依赖于其他一些机制来通知其他线程“你有一个数据包要处理”。 是的,如果你有大量的数据包要复制的话,速度会非常快 – 但是如果真的有一个巨大的差异,我会感到惊讶。 主要好处是对方不需要将数据从共享内存中复制出来,但是它也依赖于有足够的内存来保存所有的“正在运行”消息,或者发送者有能力阻止事情。
我不是说“不要用共享内存”,我只是说没有“解决所有问题最好的解决方案”之类的东西。“
为了澄清:我将开始实施一个简单的方法使用管道或命名管道[取决于哪个目的],并衡量其性能。 如果真的需要花费大量时间来复制数据,那么我会考虑使用其他方法。
当然,另一个考虑是“我们是否会用两台独立的机器(或同一个系统上的两台虚拟机)来解决这个问题,在这种情况下,网络解决方案是一个更好的选择 – 即使它不是最快的,我在工作的机器上运行了一个本地的TCP协议栈,用于基准测试,并获得了持续流量的20-30Gbit / s(2-3GB / s),同一进程中的原始memcpy大约在50-100GBit / s (5-10GB / s)(除非块大小非常小并且适合L1缓存)我没有测量过标准管道,但是我认为这个数字大概在这两个数字中间[这是数字对于许多不同规模的相当现代化的个人电脑来说都是正确的 – 显然,在ARM,MIPS或其他嵌入式控制器上,对于所有这些方法,期望一个较低的数字]
英国剑桥大学的NetOS系统研究小组已经完成了一些(开放源代码)的IPC基准测试。
源代码位于https://github.com/avsm/ipc-bench 。
项目页面: http : //www.cl.cam.ac.uk/research/srg/netos/projects/ipc-bench/ 。
结果: http : //www.cl.cam.ac.uk/research/srg/netos/projects/ipc-bench/results.html
本研究已使用上述结果发布: http : //anil.recoil.org/papers/drafts/2012-usenix-ipc-draft1.pdf
检查CMA和kdbus: https ://lwn.net/Articles/466304/
我认为现在最快的东西是基于AIO的。 http://www.kegel.com/c10k.html
那么,你可以简单地在你的进程之间有一个共享内存段,使用linux共享内存 SHM
。
这是很容易使用,看一些例子的链接。
当你用C ++标记这个问题时,我会推荐Boost.Interprocess :
共享内存是最快的进程间通信机制。 操作系统将一个内存段映射到多个进程的地址空间中,以便多个进程可以在该内存段中读写,而不用调用操作系统函数。 但是,我们需要在读取和写入共享内存的进程之间进行某种同步。
资源
我发现一个警告是同步原语的可移植性限制 。 例如,OS X和Windows都不具有进程间条件变量的本地实现,因此它使用自旋锁来模拟它们。
现在,如果您使用支持POSIX进程共享原语的* nix,则不会有任何问题。
共享内存与同步是一个很好的方法,当涉及大量的数据。
posix消息队列相当快,但它们有一些限制