在Linux上,C ++应用程序进程之间发送消息的最快技术是什么?我隐约知道桌面上有以下技术:
还有更多方法,最快的是什么?
答案 0 :(得分:37)
虽然上述所有答案都非常好,但我认为我们必须讨论什么是“最快”[并且它必须“最快”还是“足够快”?]
对于LARGE消息,毫无疑问共享内存是一种非常好的技术,并且在很多方面非常有用。
但是,如果消息很小,则必须提出自己的消息传递协议以及通知其他进程存在消息的方法存在缺陷。
在这种情况下,管道和命名管道更容易使用 - 它们的行为非常类似于文件,您只需在发送方写入数据,并在接收方读取数据。如果发送者写了一些东西,接收方会自动唤醒。如果管道已满,则发送方被阻止。如果发件人没有更多数据,则会自动阻止接收方。这意味着这可以在相当少的代码行中实现,并且非常好地保证它每次都可以在任何时候工作。
另一方面,共享内存依赖于其他一些机制来通知另一个线程“你有一个要处理的数据包”。是的,如果您要复制大量数据,速度非常快 - 但如果管道存在巨大差异,我会感到惊讶。主要的好处是对方不必将数据从共享内存中复制出来 - 但它还依赖于有足够的内存来保存所有“在飞行中”的消息,或者发送者有能力阻止事物。
我不是说“不要使用共享内存”,我只是说没有“一种能最好地解决所有问题的解决方案”。
澄清一下:我将首先使用管道或命名管道[取决于哪些目的]来实现一个简单的方法,并测量其性能。如果花费大量时间实际复制数据,那么我会考虑使用其他方法。
当然,另一个考虑应该是“我们是否会使用两台独立的机器[或同一系统上的两台虚拟机]来解决这个问题。在这种情况下,网络解决方案是更好的选择 - 即使它是不是最快的,我在我的机器上运行本地TCP堆栈用于基准测试目的,并获得了大约20-30Gbit / s(2-3GB / s)的持续流量。同一过程中的原始memcpy大约50- 100GBit / s(5-10GB / s)(除非块大小真的很小并且适合L1缓存)。我没有测量过标准管道,但我预计它大概在这两个数字的中间。[这个数字适用于许多不同的中型相当现代的PC - 显然,在ARM,MIPS或其他嵌入式控制器上,期望所有这些方法的数字更低]
答案 1 :(得分:13)
我建议也要考虑一下:How to use shared memory with Linux in C。
基本上,当在一台机器上进行IPC时,我会丢弃TCP和UDP等网络协议。它们具有打包开销,并且受到更多资源的限制(例如端口,环回接口)。
答案 2 :(得分:7)
英国剑桥大学的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
答案 3 :(得分:3)
检查CMA和kdbus: https://lwn.net/Articles/466304/
我认为现在最快的东西都是基于AIO。 http://www.kegel.com/c10k.html
答案 4 :(得分:2)
当您使用C ++标记此问题时,我建议使用Boost.Interprocess:
共享内存是最快的进程间通信机制。该 操作系统在几个地址空间中映射一个内存段 进程,以便多个进程可以在该内存中读写 段不调用操作系统功能。但是,我们需要 读写进程之间的某种同步 共享内存。
我发现的一个警告是portability limitations for synchronization primitives。 Nor OS X和Windows都没有针对进程间条件变量的本机实现,例如, 所以它用旋转锁模仿它们。
现在,如果您使用支持POSIX进程共享原语的* nix,则不会有任何问题。
当涉及大量数据时,带有同步的共享内存是一种很好的方法。
答案 5 :(得分:1)
好吧,您可以使用the linux shared memory又称SHM
在您的流程之间创建共享内存段。
这很容易使用,请查看链接以获取一些示例。
答案 6 :(得分:0)
posix message queues非常快,但它们有一些限制