D-Bus 简介

D-Bus 的英文全称是 Desktop Bus,从名字可以看出它最早是被设计用于桌面操作系统的通信总线,即桌面应用程序和操作系统内核间的通信。D-Bus 提供了一种进程间通信及远程过程调用机制,从而实现多个不同的应用程序在同一台电脑上同时进行通信。

D-Bus 作为 freedesktop.org 项目的一部分,其设计目的是使 Linux 桌面环境提供的服务标准化。同时,freedesktop.org 项目也开发了一个称为 libdbus 的自由及开放原始码软件库,作为规范的参考实现。因此,libdbus 库常与 D-Bus 本身混淆。当然,也存在着其他的 D-Bus 实现,例如 GDBus(GNOME),QtDBus(Qt),dbus-java 以及 sd-bus(systemd 的一部分)。

功能概述

D-Bus 可用于同一个桌面会话中不同桌面应用软件间的通信,能集成桌面会话,也解决了进程的生命周期的问题。它也允许桌面会话与操作系统间的通信,这通常包括了内核与任何的系统守护进程或一般进程间的通信。

当大量的程序进行通信时,由于程序跟程序之间必须创建起一对一的通信,则整体的通信网络将会非常复杂,而通信效率也会因此低下不可靠。D-Bus 提供了一个软件汇流抽象层,能够汇整所有的消息到一个虚拟的通信频道。连接到 D-Bus 的程序无法也无需知道 D-Bus 是如何操作,只需遵从 D-Bus 的标准,就能保证所有连接到 D-Bus 的程序能进行彼此间的交流。换句话说,D-Bus 是一个消息总线系统,即进程间通信的介质,让应用程序间可以通信并交换消息。

Linux 桌面环境通过实例化多个总线来利用 D-Bus 设施,特别是:

  • 一个单一的系统总线,可供系统的所有用户和进程使用,它提供对系统服务(即操作系统和任何系统守护程序提供的服务)的访问;
  • 每个用户登录会话的会话总线,为同一桌面会话中的用户应用程序提供桌面服务,并允许将桌面会话集成为一个整体。

一个进程可以连接到任意数量的 D-Bus 总线上,前提是它已被授予访问这些总线的权限。实际上,这意味着任何用户进程都可以连接到系统总线及其当前会话总线,但不能连接到另一个用户的会话总线,甚至不能连接到同一用户拥有的不同会话总线。如果将所有用户会话组合到单个用户总线中,则后一种限制可能会在未来发生变化。

利用 D-Bus 可以很方便地为应用程序增加新的功能,简化已有功能,包含信息分享、模块化及权限分离。例如当使用蓝牙接收到通话时,通知所有正在运行中的音乐播放器,使其静音或暂停播放,直到通话结束。

D-Bus 也可以用作框架来集成用户应用程序的不同组件。例如,办公套件可以通过会话总线进行通信,以在文字处理器和电子表格之间共享数据。

通信特点

D-Bus 是一种低延迟、低开销、高可用性的进程间通信机制。其协议是二进制的,避免序列化的过程,通信效率较高。D-Bus 可以提供一些更高层的功能:

  1. 结构化的名字空间;
  2. 独立于架构的数据格式;
  3. 支持消息中的大部分通用数据元素;
  4. 带有异常处理的通用远程调用接口;
  5. 支持广播类型的通信。

消息类型

连接到 D-Bus 总线的进程可通过总线接收或传递消息,总线收到消息时,根据不同的消息类型进行不同的处理。

D-Bus 总线中的消息可分为以下四类:

  1. Methodcall 消息:将触发一个函数调用;
  2. Methodreturn 消息:触发函数调用返回的结果;
  3. Error 消息:触发的函数调用返回一个异常;
  4. Signal 消息:通知,可以看作为事件消息。

应用场景

D-Bus 提供了一种高效的进程间通信机制,因此主要用于进程间函数调用以及进程间信号广播。

  • 函数调用

    D-Bus 可以实现进程间函数调用,进程 A 发送函数调用的请求(Methodcall 消息),经过总线转发至进程 B。进程 B 将应答函数返回值(Method return 消息)或者错误消息(Error 消息)。

  • 消息广播

    进程间消息广播(Signal 消息)不需要响应,接收方需要向总线注册感兴趣的消息类型,当总线接收到 “Signal 消息” 类型的消息时,会将消息转发至希望接收的进程。

相关实现

  • libdbus
  • GDBus
  • QtDBus
  • sd-bus
  • libnih-dbus
  • kdbus
  • zbus
  • Protocol::DBus

相关链接

  • D-Bus 教程:https://dbus.freedesktop.org/doc/dbus-tutorial.html
  • GitHub 地址:https://github.com/freedesktop/dbus