使用哪种Linux IPC技术?


74

我们仍处于项目的设计阶段,但我们正在考虑在嵌入式Linux内核上具有三个独立的进程。进程之一是通信模块,该模块处理通过各种介质往返于设备的所有通信。

其他两个过程将需要能够通过通信过程发送/接收消息。我正在尝试评估Linux提供的IPC技术。其他进程将发送的消息的大小将有所不同,从调试日志到流媒体,速率约为5 Mbit。同样,媒体可能同时流入和流出。

您将为该应用建议哪种IPC技术? http://en.wikipedia.org/wiki/进程间通信

如果发生任何变化,处理器的运行速度约为400-500 Mhz。无需跨平台,仅Linux即可。需要使用C或C ++实现。


36
Linux内核提供以下IPC机制:信号,匿名管道,命名管道或FIFO,SysV消息队列,POSIX消息队列,SysV共享内存,POSIX共享内存,SysV信号量,POSIX信号量,FUTEX锁,文件支持和匿名共享使用mmap,UNIX域套接字,Netlink套接字,网络套接字,Inotify机制,FUSE子系统,D-Bus子系统的内存。对于大多数需求,我使用套接字。
狂热爱好者

2
@enthusiasticgeek D-Bus完全在用户空间中完成。一些内核专家正在研究kdbus,但仍在进行中。
new123456 2014年

在arm926ejs 200MHz处理器上,带有两个uint32参数的方法调用和答复消耗的时间介于0到15毫秒之间。平均6毫秒。别人如何看待其他处理器?
minghua 2014年

1
比较Unix / Linux IPC的可能副本这可能范围太广,并且倾向于退化为那个。
西罗Santilli郝海东冠状病六四事件法轮功

有关“经典” Linux IPC机制的评论:请参见此处
Reblochon Masque

Answers:


34

我会选择Unix域套接字:比IP套接字(即,没有机器间通信)的开销少,但其他方面也很方便。


我正在尝试此方法,但结果不尽相同。如果有几个进程试图与我的ipc服务器(unix套接字服务器)通信-我需要多路复用吗?
User9102d82 '19

@ User9102d82:是的,请使用select()(或poll())函数来实现。它们可以监视多个文件描述符(例如,您的客户端套接字),阻塞直到有一个可供读取的数据。请参阅notes.shichao.io/unp/ch6以获取良好的概述。
sigma,

68

选择IPC时,应考虑性能差异的原因,包括传输缓冲区大小,数据传输机制,内存分配方案,锁定机制的实现,甚至代码复杂性。

在可用的IPC机制中,性能的选择通常取决于Unix域套接字命名管道(FIFO)。我读了一篇有关各种进程间通信机制的性能分析的论文,该论文指出IPC的Unix域套接字可能提供最佳性能。我在其他地方看到了矛盾的结果,这表明管道可能会更好。

当发送少量数据时,为简化起见,我更喜欢使用命名管道(FIFO)。这需要一对命名管道进行双向通信。Unix域套接字在设置(套接字创建,初始化和连接)上花费了更多的开销,但是更加灵活,并且可以提供更好的性能(更高的吞吐量)。

您可能需要针对特定​​的应用程序/环境运行一些基准测试,以确定最适合您的方法。根据提供的描述,听起来Unix域套接字可能是最合适的。


Beej的Unix IPC指南非常适合Linux / Unix IPC入门。


20

不能相信没有人提到dbus。

http://www.freedesktop.org/wiki/Software/dbus

http://en.wikipedia.org/wiki/D-Bus

如果您的应用程序在结构上很简单,则可能会有点过高,在这种情况下-在性能至关重要的受控嵌入式环境中-您无法击败共享内存。


4
Dbus在嵌入式环境中存在性能问题。它创建了许多上下文切换,因为您是通过dbus创建一条消息,然后将其发送到内核,然后再将其发送回dbus。有一个修补程序使用称为AF_BUS的新套接字类型来减少这些上下文切换,但是Red Hat出于某种原因未应用该修补程序。
耶利米2012年

4
这种许多上下文切换的设计指向dbus的最初目标,即成为服务发现总线而不是IPC机制。
耶利米2012年

@耶利米:关于嵌入式环境中性能问题的细节?我做了一些分析和在线研究,没有看到一个严重的问题。看到这里
-minghua

当然,这取决于您要寻找的性能类型。例如,在索引音频时,使用dbus的bluez之类的东西显然会将大量对象推入管道。这会产生大量流量,并且您可能会看到性能下降。作为IPC机制,至少与专门为嵌入式构建的其他POSIX IPC机制相比,它变得缓慢。kdbus旨在解决其中一些性能问题,但它仍是一个新项目。
jeremiah 2014年

12

如果性能确实成为问题,则可以使用共享内存-但比其他方法要复杂得多-您将需要一种信号传输机制来发出信号,表明数据已准备就绪(信号量等)以及用于防止并发访问结构的锁在对其进行修改时。

好处是您可以传输大量数据而不必将其复制到内存中,这肯定会在某些情况下提高性能。

也许有可用的库通过共享内存提供更高级别的原语。

共享内存通常是通过使用MAP_SHARED映射同一文件来获得的(如果您不希望持久化,可以在tmpfs上);许多应用程序还使用System V共享内存(出于愚蠢的历史原因,恕我直言;对同一件事它的界面要差很多)


将IPC文件用于mmap是否会将数据写入持久存储?
Abhiarora

如果该文件位于tmpfs内存文件系统中,则不会。通常用于此目的。
MarkR

4

在撰写本文时(2014年11月),Kdbus和Binder已离开linux内核的暂存分支。目前尚不能保证两者都能加入,但两者的前景都是乐观的。Binder是Android中的轻量级IPC机制,Kdbus是内核中的类似dbus的IPC机制,它减少了上下文切换,从而大大加快了消息传递速度。

还有“透明的进程间通信”或TIPC,它很健壮,对于群集和多节点设置很有用。http://tipc.sourceforge.net/


0

Unix域套接字将满足您的大多数IPC要求。在这种情况下,由于内核提供了此IPC工具,因此您实际上不需要专用的通信过程。另外,请看一下POSIX消息队列,我认为它是Linux中利用率最差的IPC之一,但在需要n:1通信的许多情况下非常方便。


通过“ n:1”,您是说n个进程与单个进程对话吗?请确认。
User9102d82 '19
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.