在Linux上在进程之间传递消息的最快技术

Fastest technique to pass messages between processes on Linux?

本文关键字:技术 消息 Linux 进程 之间      更新时间:2023-10-16

在Linux上c++应用程序进程之间发送消息最快的技术是什么?我模模糊糊地意识到下面这些技术是可以使用的:

  • TCP
  • UDP
  • 套接字
  • 管道
  • 命名管道
  • 内存映射文件

还有其他方法吗?最快的方法是什么?

虽然以上所有的答案都很好,但我认为我们必须讨论什么是"最快",它必须是"最快"还是"足够快"?)

对于LARGE消息,共享内存无疑是一种非常好的技术,在很多方面都非常有用。

但是,如果消息很小,则必须提出自己的消息传递协议和通知其他进程有消息的方法,这是有缺点的。

管道和命名管道在这种情况下更容易使用-它们的行为非常像文件,您只需在发送端写入数据,并在接收端读取数据。如果发送方写了一些东西,接收方就会自动唤醒。如果管道已满,则发送端被阻塞。如果没有来自发送方的数据,接收方将自动阻塞。这意味着这可以在相当少的代码行中实现,并且可以很好地保证它在任何时候都能正常工作。

另一方面,共享内存依赖于一些其他机制来通知另一个线程"你有一个数据包要处理"。是的,如果你有大量的数据包要复制,它是非常快的——但是如果管道有巨大的不同,我会感到惊讶,真的。主要的好处是另一方不需要从共享内存中复制数据——但它也依赖于有足够的内存来保存所有"正在飞行"的消息,或者发送方有能力保留东西。

我不是说"不要使用共享内存",我只是说没有所谓的"一个解决方案可以最好地解决所有问题"。

澄清一下:我将首先使用管道或命名管道实现一个简单的方法[取决于哪个适合目的],并测量其性能。如果实际复制数据要花费大量时间,那么我会考虑使用其他方法。

当然,另一个考虑应该是"我们是否要使用两个独立的机器[或同一系统上的两个虚拟机]来解决这个问题。"在这种情况下,网络解决方案是更好的选择——即使它不是最快的,我已经在我的机器上运行了一个本地TCP堆栈用于基准测试,并且在持续的流量下获得了20- 30gb/s (2-3GB/s)的速度。同一进程中的原始内存大约为50- 100gb/s (5-10GB/s)(除非块大小非常小,适合L1缓存)。我没有测量过标准管道,但我估计它大概在这两个数字的中间。

我建议也看看这个:如何在c中使用Linux的共享内存

基本上,当在一台机器上执行IPC时,我会放弃TCP和UDP等网络协议。它们有封装开销,并且绑定到更多的资源(例如端口、环回接口)。

来自英国剑桥大学的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

既然您用c++标记了这个问题,我建议您使用Boost。进程间:

共享内存是最快的进程间通信机制。的操作系统在若干地址空间中映射一个内存段进程,以便多个进程可以在该内存中读写段,不调用操作系统函数。然而,我们需要读写进程之间的某种同步共享内存。

来源

我发现的一个警告是同步原语的可移植性限制。OS X和Windows都没有进程间条件变量的本地实现,例如,所以它用自旋锁来模拟它们。

现在如果你使用支持POSIX进程共享原语的*nix,就不会有问题了。

当涉及到大量数据时,带同步的共享内存是一种很好的方法。

那么,您可以简单地在进程之间使用linux共享内存SHM共享内存段。

它非常容易使用,查看链接中的一些示例。

posix消息队列非常快,但是它们有一些限制