进程间通信-Dbus

整理文档很辛苦,赏杯茶钱您下走!

免费阅读已结束,点击下载阅读编辑剩下 ...

阅读已结束,您可以下载文档离线阅读编辑

资源描述

1.Dbus1.1D-Bus三层架构D-Bus是一个为应用程序间通信的消息总线系统,用于进程之间的通信。它是个3层架构的IPC系统,包括:1、函数库libdbus,用于两个应用程序互相联系和交互消息。2、一个基于libdbus构造的消息总线守护进程demon,可同时与多个应用程序相连,并能把来自一个应用程序的消息路由到0或者多个其他程序。3、基于特定应用程序框架的封装库或捆绑(wrapperlibrariesorbindings)。例如,libdbus-glib和libdbus-qt,还有绑定在其他语言,例如Python的。大多数开发者都是使用这些封装库的API,因为它们简化了D-Bus编程细节。libdbus被有意设计成为更高层次绑定的底层后端(low-levelbackend)。大部分libdbus的API仅仅是为了用来实现绑定。1.2总线在D-Bus中,“bus”是核心的概念,它是一个通道:不同的程序可以通过这个通道做些操作,比如方法调用、发送信号和监听特定的信号。在一台机器上总线守护有多个实例(instance)。这些总线之间都是相互独立的。一个持久的系统总线(systembus):它在引导时就会启动。这个总线由操作系统和后台进程使用,安全性非常好,以使得任意的应用程序不能欺骗系统事件。它是桌面会话和操作系统的通信,这里操作系统一般而言包括内核和系统守护进程。这种通道的最常用的方面就是发送系统消息,比如:插入一个新的存储设备;有新的网络连接;等等。还将有很多会话总线(sessionbuses):这些总线当用户登录后启动,属于那个用户私有。它是用户的应用程序用来通信的一个会话总线。同一个桌面会话中两个桌面应用程序的通信,可使得桌面会话作为整体集成在一起以解决进程生命周期的相关问题。这在GNOME和KDE桌面中大量使用。  对于一些远程的工作站,在systembus中可能会有一些问题,例如热插拔,是否需要通知远端的terminal,这会使得kernel暴露一些设备的能力,不过,我们现在关心D-Bus,是因为手持终端设备的使用,这些将不会出现。在InternetTablet,也包括我们的手机系统,所有的应用程序都是使用一个用户ID运行的,所以只有一个会话通道,这一点是和Linux桌面系统是有明显区别的。  D-Bus是低延迟而且低开销的,设计得小而高效,以便最小化传送的往返时间。另外,协议是二进制的,而不是文本的,这样就排除了费时的序列化过程。从开发者的角度来看,D-BUS是易于使用的。有线协议容易理解,客户机程序库以直观的方式对其进行包装。D-Bus的主要目的是提供如下的一些更高层的功能:A、结构化的名字空间B、独立于架构的数据格式C、支持消息中的大部分通用数据元素D、带有异常处理的通用远程调用接口E、支持广播类型的通信1.3Busdaemon总线守护Busdaemon是一个特殊的进程:这个进程可以从一个进程传递消息给另外一个进程。当然了,如果有很多applications链接到这个通道上,这个daemon进程就会把消息转发给这些链接的所有程序。在最底层,D-Bus只支持点对点的通信,一般使用本地套接字(AF_UNIX)在应用和busdaemon之间通信。D-Bus的点对点是经过busdaemon抽象过的,由busdaemon来完成寻址和发送消息,因此每个应用不必要关心要把消息发给哪个进程。D-Bus发送消息通常包含如下步骤(正常情况下):创建和发送消息给后台busdaemon进程,这个过程中会有两个上下文的切换。后台busdaemon进程会处理该消息,并转发给目标进程,这也会引起上下文的切换目标程序接收到消息,然后根据消息的种类,做不同的响应:要么给个确认、要么应答、还有就是忽略它。最后一种情况对于“通知”类型的消息而言,前两种都会引起进一步的上下文切换。综上原因,如果你准备在不同的进程之间传递大量的数据,D-Bus可能不是最有效的方法,最有效的方法是使用共享内存,但是对共享内存的管理也是相当复杂的。D-Bus进程通信简单框架1.4D-Bus常见概念1.4.1原生对象和对象路径所有使用D-BUS的应用程序都包含一些对象,当经由一个D-BUS连接收到一条消息时,该消息是被发往一个对象而不是整个应用程序。在开发中程序框架定义着这样的对象,例如JAVA,GObject,QObject等等,在D-Bus中成为nativeobject。对于底层的D-Bus协议,即libdbusAPI,并不理会这些nativeobject,它们使用的是一个叫做objectpath的概念。通过objectpath,高层编程可以为对象实例进行命名,并允许远程应用引用它们。这些名字看起来像是文件系统路径,例如一个对象可能叫做“/org/kde/kspread/sheets/3/cells/4/5”。易读的路径名是受鼓励的做法,但也允许使用诸如“/com/mycompany/c5yo817y0c1y1c5b”等,只要它可以为你的应用程序所用。Namespacing的对象路径以开发者所有的域名开始(如/org/kde)以避免系统不同代码模块互相干扰。简单地说:一个应用创建对象实例进行D-Bus的通信,这些对象实例都有一个名字,命名方式类似于路径,例如/com/mycompany,这个名字在全局(session或者system)是唯一的,用于消息的路由。1.4.2方法和信号MethodsandSignals每一个对象有两类成员:方法和信号。方法就是JAVA中同样概念,方法是一段函数代码,带有输入和输出。信号是广播给所有兴趣的其他实体,信号可以带有数据payload。在D-BUS中有四种类型的消息:方法调用(methodcalls)、方法返回(methodreturns)、信号(signals)和错误(errors)。要执行D-BUS对象的方法,您需要向对象发送一个方法调用消息。它将完成一些处理(就是执行了对象中的Method,Method是可以带有输入参数的。)并返回,返回消息或者错误消息。信号的不同之处在于它们不返回任何内容:既没有“信号返回”消息,也没有任何类型的错误消息。1.4.3接口Interface每一个对象支持一个或者多个接口,接口是一组方法和信号,接口定义一个对象实体的类型。D-Bus对接口的命名方式,类似org.freedesktop.Introspectable。开发人员通常将使用编程语言类的的名字作为接口名字。1.4.4Proxies代理代理对象用来表示其他的remoteobject。当我们触发了proxy对象的method时,将会在D-Bus上发送一个method_call的消息,并等待答复,根据答复返回。使用非常方便,就像调用一个本地的对象。1.4.5BusNames总线名字  当一个应用连接到busdaemon,daemon立即会分配一个名字给这个连接,称为uniqueconnectionname,这个唯一标识的名字以冒号:开头,例如:34-907,这个名字在daemon的整个生命周期是唯一的。但是这种名字总是临时分配,无法确定的,也难以记忆,因此应用可以要求有另外一个名字well-knownname来对应这个唯一标识,就像我们使用域名来对应IP地址一样。例如可以使用com.mycompany来映射:34-907。应用程序可能会要求拥有额外的周知名字(well-knownname)。例如,你可以写一个规范来定义一个名字叫做com.mycompany.TextEditor。你的协议可以指定自己拥有这个名字,一个应用程序应该在路径/com/mycompany/TextFileManager下有一个支持接口org.freedesktop.FileHandler的对象。应用程序就可以发送消息到这个总线名字,对象,和接口以执行方法调用。当一个应用结束或者崩溃是,OSkernel会关闭它的总线连接。总线发送notification消息告诉其他应用,这个应用的名字已经失去他的owner。当检测到这类notification时,应用可以知道其他应用的生命周期。这种方式也可用于只有一个实例的应用,即不开启同样的两个应用的情况。1.4.6地址连接建立有server和client,对于busdaemon,应用就是client,daemon是server。一个D-Bus的地址是指server用于监听,client用于连接的地方,例如unix:path=/tmp/abcedf标识server将在路径/tmp/abcedf的UNIXdomainsocket监听。地址可以是指定的TCP/IPsocket或者其他在或者将在D-Bus协议中定义的传输方式。如果使用busdaemon,libdbus将通过读取环境变量自动获取sessionbusdamon的地址,通过检查一个指定的UNIXdomainsocket路径获取systembus的地址。如果使用D-bus,但不是daemon,需要定义那个应用是server,那个是client,并定义一套机制是他们认可server的地址,这不是通常的做法。  通过上面的描述,我们可以获得下面的视图:Address–[BusName]–Path–Interface–Methodbusname不是必要的,它只在daemon的情况下用于路由,点对点的直接连接是不需要的。简单地说:Address是D-Bus中server用来监听client的地址,当一个client连接上D-Bus,通常是Daemo的方式,这个client就有了一个BusName。其他应用可以根据消息中所带的BusName,来判断和哪个应用相关。消息在总线中传递的时候,传递到应用中,再根据objectpath,送至应用中具体的对象实例中,也就是是应用中根据Interface创建的对象。这些Interface有method和singal两种,用来发送、接收、响应消息。1.5D-Bus消息消息通过D-Bus在进程间传递。有四类消息:一、Methodcall消息:将触发对象的一个method二、Methodreturn消息:触发的方法返回的结果三、Error消息:触发的方法返回一个异常四、Signal消息:通知,可以看作为事件消息。一个消息有消息头header,里面有field,有一个消息体body,里面有参数arguments。消息头包含消息体的路由信息,消息体就是净荷payload。头字段可能包括发送者的bus名,目的地的bus名,方法或者signal名等等,其中一个头字段是用于描述body中的参数的类型,例如“i”标识32位整数,ii”表示净荷为2个32为整数。1.5.1发送Methodcall消息的场景一个methodcall消息从进程A到进程B,B将应答一个methodreturn消息或者error消息。在每个call消息带有一个序列号,应答消息也包含同样的号码,使之可以对应起来。他们的处理过程如下:如果提供proxy,通过触发本地一个对象的方法从而触发另一个进程的远端对象的方法。应用调用proxy的一个方法,proxy构造一个methodcall消息发送到远端进程。对于底层的API,不使用proxy,应用需要自己构造methodcall消息。一个methodcall消息包含:远端进程的busname,方法名字,方法的参数,远端进程中objectpath,可选的接口名字。methodcall消息发送到busdaemonbusdaemon查看目的地的busname。如果一个进程对应这个名字,busdaemon将methodcall消息发送到该进程中。如果没有发现匹配,busdaemon创建一个error消息作为应答返回。进程接收后将methodcall消息分拆。对于简单的底层API情况,将立即执行方法,并发送一个methodreply消息给busdaemon。对于高层的API,将检查对象path,interface和method,触发一个nat

1 / 19
下载文档,编辑使用

©2015-2020 m.777doc.com 三七文档.

备案号:鲁ICP备2024069028号-1 客服联系 QQ:2149211541

×
保存成功