【问题标题】:Which Linux IPC technique to use?使用哪种 Linux IPC 技术?
【发布时间】:2011-01-17 21:09:08
【问题描述】:

我们仍处于项目的设计阶段,但我们正在考虑在嵌入式 Linux 内核上设置三个独立的进程。其中一个进程是通信模块,它通过各种媒介处理与设备之间的所有通信。

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

您会为此应用推荐哪种 IPC 技术? http://en.wikipedia.org/wiki/Inter-process_communication

处理器运行在 400-500 Mhz 左右,如果这有任何改变的话。 不需要跨平台,只有Linux就可以。 需要用 C 或 C++ 实现。

【问题讨论】:

  • Linux内核提供以下IPC机制:信号、匿名管道、命名管道或FIFO、SysV消息队列、POSIX消息队列、SysV共享内存、POSIX共享内存、SysV信号量、POSIX信号量、FUTEX锁、使用 mmap 的文件支持和匿名共享内存、UNIX 域套接字、Netlink 套接字、网络套接字、Inotify 机制、FUSE 子系统、D-Bus 子系统。对于我的大部分需求,我使用套接字。
  • @motiveicgeek D-Bus 完全在用户空间中完成。一些内核人员正在开发kdbus,但它仍在进行中。
  • 在 arm926ejs 200MHz 处理器上,使用两个 uint32 参数进行方法调用和回复会消耗 0 到 15 毫秒之间的任何时间。平均 6 毫秒。其他人如何看待其他处理器?
  • Comparing Unix/Linux IPC 的可能重复项 这一项可能过于宽泛,并且倾向于退化为那一项。
  • 对于“经典”Linux IPC 机制的回顾:参见here

标签: linux ipc


【解决方案1】:

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

在可用的 IPC 机制中,性能选择通常归结为Unix domain socketsnamed pipes (FIFOs)。我在Performance Analysis of Various Mechanisms for Inter-process Communication 上阅读了一篇论文,指出用于 IPC 的 Unix 域套接字可能提供最佳性能。我看到了相互矛盾的结果elsewhere,这表明管道可能更好。

当发送少量数据时,我更喜欢命名管道 (FIFO),因为它们很简单。这需要一对命名管道进行双向通信。 Unix 域套接字的设置(套接字创建、初始化和连接)需要更多开销,但更灵活并且可能提供更好的性能(更高的吞吐量)。

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


Beej's Guide to Unix IPC 非常适合 Linux/Unix IPC 入门。

【解决方案2】:

我会选择 Unix 域套接字:开销比 IP 套接字少(即没有机器间通信),但同样方便。

【讨论】:

  • 我正在尝试这个,但我得到的结果好坏参半。如果有几个进程试图与我的 ipc 服务器(unix 套接字服务器)通信 - 我需要多路复用吗?
  • @User9102d82:是的,使用select()(或poll())函数来实现。这些可以监视多个文件描述符(例如您的客户端套接字),阻塞直到有数据可供读取。请参阅notes.shichao.io/unp/ch6 以获得良好的概述。
【解决方案3】:

不敢相信没有人提到 dbus。

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

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

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

【讨论】:

  • Dbus 在嵌入式环境中存在性能问题。它创建了大量的上下文切换,因为您通过 dbus 创建一条消息,将其发送到内核,然后将其发送回 dbus。有一个补丁可以使用称为 AF_BUS 的新套接字类型减少这些上下文切换,但 Red Hat 出于某种原因没有应用该补丁。
  • 这种多上下文切换的设计指向 dbus 的最初目标是成为服务发现总线,而不是 IPC 机制。
  • @jeremiah:关于嵌入式环境中的性能问题的任何细节?我做了一些分析和在线研究,没有看到严重的问题。见here
  • 这当然取决于您要寻找的性能类型。例如,使用 dbus 的 bluez 之类的东西在索引音频时显然会将大量对象推到管道中。这会产生大量流量,您可能会看到性能下降。作为一种 IPC 机制,它变得很慢,至少与其他专门为嵌入式构建的 POSIX IPC 机制相比。 kdbus 旨在解决其中一些性能问题,但它仍然是一个新项目。
【解决方案4】:

如果性能真的成为问题,您可以使用共享内存 - 但它比其他方法复杂得多 - 您需要一种信号机制来表示数据已准备好(信号量等)以及防止并发的锁在修改结构时访问它们。

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

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

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

【讨论】:

  • 是否会为 mmap 使用 IPC 文件将数据写入持久存储?
  • 如果文件位于 tmpfs 内存文件系统中,则不会。这通常用于此类目的。
【解决方案5】:

截至撰写本文时(2014 年 11 月),Kdbus 和 Binder 已离开 linux 内核的暂存分支。目前无法保证其中任何一个都会进入,但两者的前景都有些乐观。 Binder 是 Android 中的轻量级 IPC 机制,Kdbus 是内核中类似 dbus 的 IPC 机制,减少了上下文切换,从而大大加快了消息传递的速度。

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

【讨论】:

    【解决方案6】:

    Unix 域套接字将满足您的大部分 IPC 要求。在这种情况下,您实际上并不需要专门的通信进程,因为内核提供了这种 IPC 设施。另外,看看 POSIX 消息队列,我认为它是 Linux 中使用率最低的 IPC 之一,但在许多需要 n:1 通信的情况下非常方便。

    【讨论】:

    • 'n:1',你的意思是n个进程与一个进程通信吗?请确认。
    猜你喜欢
    • 2011-05-27
    • 1970-01-01
    • 2011-03-26
    • 2010-10-07
    • 2013-10-16
    • 2010-09-12
    • 1970-01-01
    • 1970-01-01
    • 2013-02-01
    相关资源
    最近更新 更多