D-Bus三层架构

D-Bus是一个为应用程序间通信的消息总线系统, 用于进程之间的通信。它是个3层架构的IPC 系统,包括:

1、函数库libdbus ,用于两个应用程序互相联系和交互消息。

2、一个基于libdbus构造的消息总线守护进程,可同时与多个应用程序相连,并能把来自一个应用程序的消息路由到0或者多个其他程序。

3、基于特定应用程序框架的封装库或捆绑(wrapper libraries or bindings )。例如,libdbus-glib和libdbus-qt,还有绑定在其他语言,例如Python的。大多数开发者都是使用这些封装库的API,因为它们简化了D-Bus编程细节。libdbus被有意设计成为更高层次绑定的底层后端(low-levelbackend )。大部分libdbus的 API仅仅是为了用来实现绑定。

总线

在D-Bus中,“bus"是核心的概念,它是一个通道:不同的程序可以通过这个通道做些操作,比如方法调用、发送信号和监听特定的信号。在一台机器上总线守护有多个实例(instance)。这些总线之间都是相互独立的。

一个持久的系统总线(system bus):

它在引导时就会启动。这个总线由操作系统和后台进程使用,安全性非常好,以使得任意的应用程序不能欺骗系统事件。它是桌面会话和操作系统的通信,这里操作系统一般而言包括内核和系统守护进程。这种通道的最常用的方面就是发送系统消息,比如:插入一个新的存储设备;有新的网络连接;等等。

还将有很多会话总线(session buses):

这些总线当用户登录后启动,属于那个用户私有。它是用户的应用程序用来通信的一个会话总线。同一个桌面会话中两个桌面应用程序的通信,可使得桌面会话作为整体集成在一起以解决进程生命周期的相关问题。这在GNOME和KDE桌面中大量使用。

对于一些远程的工作站,在system bus中可能会有一些问题,例如热插拔,是否需要通知远端的terminal,这会使得kernel暴露一些设备的能力,不过,我们现在关心D-Bus,是因为手持终端设备的使用,这些将不会出现。在Internet Tablet,也包括我们的手机系统,所有的应用程序都是使用一个用户ID运行的,所以只有一个会话通道,这一点是和Linux桌面系统是有明显区别的。

D-Bus是低延迟而且低开销的,设计得小而高效,以便最小化传送的往返时间。另外,协议是二进制的,而不是文本的,这样就排除了费时的序列化过程。从开发者的角度来看,D-BUS 是易于使用的。有线协议容易理解,客户机程序库以直观的方式对其进行包装。D-Bus的主要目的是提供如下的一些更高层的功能:

A、结构化的名字空间

B、独立于架构的数据格式

C、支持消息中的大部分通用数据元素

D、带有异常处理的通用远程调用接口

E、支持广播类型的通信

Bus daemon总线守护

Bus daemon是一个特殊的进程:这个进程可以从一个进程传递消息给另外一个进程。当然了,如果有很多applications链接到这个通道上,这个 daemon进程就会把消息转发给这些链接的所有程序。在最底层,D-Bus只支持点对点的通信,一般使用本地套接字(AF_UNIX)在应用和bus daemon之间通信。D-Bus的点对点是经过busdaemon抽象过的,由busdaemon来完成寻址和发送消息,因此每个应用不必要关心要把消息发给哪个进程。D-Bus发送消息通常包含如下步骤(正常情况下):

创建和发送消息 给后台bus daemon进程,这个过程中会有两个上下文的切换。

后台bus daemon进程会处理该消息,并转发给目标进程,这也会引起上下文的切换目标程序接收到消息,然后根据消息的种类,做不同的响应:要么给个确认、要么应答、还有就是忽略它。最后一种情况对于"通知"类型的消息而言,前两种都会引起进一步的上下文切换。

综上原因,如果你准备在不同的进程之间传递大量的数据,D-Bus可能不是最有效的方法,最有效的方法是使用共享内存,但是对共享内存的管理也是相当复杂的。