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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14225010/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 18:36:57  来源:igfitidea点击:

Fastest technique to pass messages between processes on Linux?

c++linuxperformanceipclatency

提问by user997112

What is the fastest technology to send messages between C++ application processes, on Linux? I am vaguely aware that the following techniques are on the table:

在 Linux 上,在 C++ 应用程序进程之间发送消息的最快技术是什么?我隐约知道有以下技巧可供使用:

  • TCP
  • UDP
  • Sockets
  • Pipes
  • Named pipes
  • Memory-mapped files
  • TCP
  • UDP
  • 插座
  • 管道
  • 命名管道
  • 内存映射文件

are there any more ways and what is the fastest?

有没有更多的方法,什么是最快的?

采纳答案by Sam

I would suggest looking at this also: How to use shared memory with Linux in C.

我建议也看看这个:How to use shared memory with Linux in C

Basically, I'd drop network protocols such as TCP and UDP when doing IPC on a single machine. These have packeting overhead and are bound to even more resources (e.g. ports, loopback interface).

基本上,在单台机器上执行 IPC 时,我会丢弃 TCP 和 UDP 等网络协议。这些具有分组开销并且绑定到更多资源(例如端口、环回接口)。

回答by cmc

Well, you could simply have a shared memory segment between your processes, using the linux shared memoryaka SHM.

好吧,您可以简单地在进程之间使用共享内存段,使用linux 共享内存aka SHM

It's quite easy to use, look at the link for some examples.

它非常易于使用,请查看链接以获取一些示例。

回答by Alex

Check CMA and kdbus: https://lwn.net/Articles/466304/

检查 CMA 和 kdbus:https://lwn.net/Articles/466304/

I think the fastest stuff these days are based on AIO. http://www.kegel.com/c10k.html

我认为现在最快的东西是基于 AIO。 http://www.kegel.com/c10k.html

回答by Mats Petersson

Whilst all the above answers are very good, I think we'd have to discuss what is "fastest" [and does it have to be "fastest" or just "fast enough for "?]

虽然上述所有答案都非常好,但我认为我们必须讨论什么是“最快”[它必须是“最快”还是“足够快”?]

For LARGE messages, there is no doubt that shared memory is a very good technique, and very useful in many ways.

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

However, if the messages are small, there are drawbacks of having to come up with your own message-passing protocol and method of informing the other process that there is a message.

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

Pipes and named pipes are much easier to use in this case - they behave pretty much like a file, you just write data at the sending side, and read the data at the receiving side. If the sender writes something, the receiver side automatically wakes up. If the pipe is full, the sending side gets blocked. If there is no more data from the sender, the receiving side is automatically blocked. Which means that this can be implemented in fairly few lines of code with a pretty good guarantee that it will work at all times, every time.

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

Shared memory on the other hand relies on some other mechanism to inform the other thread that "you have a packet of data to process". Yes, it's very fast if you have LARGE packets of data to copy - but I would be surprised if there is a huge difference to a pipe, really. Main benefit would be that the other side doesn't have to copy the data out of the shared memory - but it also relies on there being enough memory to hold all "in flight" messages, or the sender having the ability to hold back things.

另一方面,共享内存依赖于其他一些机制来通知另一个线程“您有一个数据包要处理”。是的,如果您要复制大量数据包,它会非常快 - 但如果管道存在巨大差异,我会感到惊讶,真的。主要的好处是另一方不必从共享内存中复制数据——但它也依赖于有足够的内存来保存所有“飞行中”的消息,或者发送方有能力阻止事情.

I'm not saying "don't use shared memory", I'm just saying that there is no such thing as "one solution that solves all problems 'best'".

我不是说“不要使用共享内存”,我只是说没有“一种解决方案可以'最好'解决所有问题”这样的东西。

To clarify: I would start by implementing a simple method using a pipe or named pipe [depending on which suits the purposes], and measure the performance of that. If a significant time is spent actually copying the data, then I would consider using other methods.

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

Of course, another consideration should be "are we ever going to use two separate machines [or two virtual machines on the same system] to solve this problem. In which case, a network solution is a better choice - even if it's not THE fastest, I've run a local TCP stack on my machines at work for benchmark purposes and got some 20-30Gbit/s (2-3GB/s) with sustained traffic. A raw memcpy within the same process gets around 50-100GBit/s (5-10GB/s) (unless the block size is REALLY tiny and fits in the L1 cache). I haven't measured a standard pipe, but I expect that's somewhere roughly in the middle of those two numbers. [This is numbers that are about right for a number of different medium-sized fairly modern PC's - obviously, on a ARM, MIPS or other embedded style controller, expect a lower number for all of these methods]

当然,另一个考虑应该是“我们是否会使用两台独立的机器[或同一系统上的两台虚拟机]来解决这个问题。在这种情况下,网络解决方案是更好的选择——即使它不是最快的, 我已经在我的机器上运行了一个本地 TCP 堆栈用于基准测试,并获得了一些 20-30Gbit/s (2-3GB/s) 的持续流量。同一进程中的原始 memcpy 大约为 50-100GBit/s (5-10GB/s)(除非块大小非常小并且适合 L1 缓存)。我没有测量标准管道,但我预计它大约在这两个数字的中间。[这是数字这对于许多不同的中型相当现代的 PC 来说都是正确的——显然,在 ARM、MIPS 或其他嵌入式控制器上,所有这些方法的数字都较低]

回答by pepper_chico

As you tagged this question with C++, I'd recommend Boost.Interprocess:

当你用 C++ 标记这个问题时,我推荐Boost.Interprocess

Shared memory is the fastest interprocess communication mechanism. The operating system maps a memory segment in the address space of several processes, so that several processes can read and write in that memory segment without calling operating system functions. However, we need some kind of synchronization between processes that read and write shared memory.

Source

共享内存是最快的进程间通信机制。操作系统将一个内存段映射到多个进程的地址空间中,这样多个进程就可以在该内存段中进行读写操作,而无需调用操作系统函数。但是,我们需要在读取和写入共享内存的进程之间进行某种同步。

来源

One caveat I've found is the portability limitations for synchronization primitives. Nor OS X, nor Windows have a native implementation for interprocess condition variables, for example, and so it emulates them with spin locks.

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

Now if you use a *nix which supports POSIX process shared primitives, there will be no problems.

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

Shared memory with synchronization is a good approach when considerable data is involved.

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

回答by arash kordi

posix message queuesare pretty fast but they have some limitations

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

回答by DejanLekic

NetOS Systems Research Group from Cambridge University, UK has done some (open-source) IPC benchmarks.

英国剑桥大学的 NetOS 系统研究小组已经完成了一些(开源)IPC 基准测试。

Source code is located at https://github.com/avsm/ipc-bench.

源代码位于https://github.com/avsm/ipc-bench

Project page: 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: http://www.cl.cam.ac.uk/research/srg/netos/projects/ipc-bench/results.html

结果:http: //www.cl.cam.ac.uk/research/srg/netos/projects/ipc-bench/results.html

This research has been published using the results above: http://anil.recoil.org/papers/drafts/2012-usenix-ipc-draft1.pdf

这项研究已使用上述结果发表:http: //anil.recoil.org/papers/drafts/2012-usenix-ipc-draft1.pdf