【转载】DBUS及常用接口介绍
转自:https://blog.csdn.net/mr_wangning/article/details/60324291
DBUS是一种高级的进程间通信机制。DBUS支持进程间一对一和多对多的对等通信,在多对多的通讯时,需要后台进程的角色去分转消息,当一个进程发消息给另外一个进程时,先发消息到后台进程,再通过后台进程将信息转发到目的进程。DBUS后台进程充当着一个路由器的角色。
DBUS中主要概念为总线,连接到总线的进程可通过总线接收或传递消息,总线收到消息时,根据不同的消息类型进行不同的处理。DBUS中消息分为四类:
1. Methodcall消息:将触发一个函数调用 ;
2. Methodreturn消息:触发函数调用返回的结果;
3. Error消息:触发的函数调用返回一个异常 ;
4. Signal消息:通知,可以看作为事件消息。
1.2 DBUS应用场景
根据DBUS消息类型可知,DBUS提供一种高效的进程间通信机制,主要用于进程间函数调用以及进程间信号广播。
1 . 函数调用
DBUS可以实现进程间函数调用,进程A发送函数调用的请求(Methodcall消息),经过总线转发至进程B。进程B将应答函数返回值(Method return消息)或者错误消息(Error消息)。
2 . 消息广播
进程间消息广播(Signal消息)不需要响应,接收方需要向总线注册感兴趣的消息类型,当总线接收到“Signal消息”类型的消息时,会将消息转发至希望接收的进程。
1.3 DBUS通信特点
DBUS是一种低延迟、低开销、高可用性的进程间通信机制。其协议是二进制的,避免序列化的过程,通信效率较高。DUBUS可以提供一些更高层的功能:
1. 结构化的名字空间;
2. 独立于架构的数据格式;
3. 支持消息中的大部分通用数据元素;
4. 带有异常处理的通用远程调用接口;
5. 支持广播类型的通信。2. 技术实现
2.1 实现原理
DBUS是一种高级的IPC通信机制,通信流程如图 2‑1所示。在DBUS通信过程中,存在一个后台进程(BUS Daemon Process)。后台进程和普通进程间信息交互是通过域套接字进行通信。
如图 2‑1所示,进程1(Process1)需先连接到总线(dbus_bus_get),其次构造消息(dbus_message_new_signal),然后发送消息(dbus_connection_send)到后台进程。后台进程接收消息,然后根据消息类型对消息进行不同处理(bus_dispatch_matches)。
进程2(Process2)接收消息前需要连接到总线,并告知总线自己希望得到的消息类型(dbus_bus_add_match),然后等待接收消息(dbus_connection_pop_message)。进程2(Process2)收到总线转发的消息时会根据消息类型,做不同的处理(若是信号类型则不需要发送返回值给总线)。
2.2 连接到总线
进程间通信前,需要连接到总线。调用dbus_bus_get函数连接进程到总线,建立进程和总线之间的连接(DBusConnection)。建立连接后,需要为这个连接注册名称,方便后面对这个连接进行操作,调用dbus_bus_request_name函数对连接进行注册名称。
建立连接和注册名称是在程序开始时执行,程序结束时,调用dbus_connection_close函数关闭一个连接。函数接口声明如程序清单 2‑1所示。
程序清单 2-1 建立、注册名称和关闭连接
- DBusConnection *dbus_bus_get (DBusBusType type, DBusError *error) /* 建立和总线的连接 */
- int dbus_bus_request_name (DBusConnection *connection,
- const char *name,
- unsigned int flags,
- DBusError *error) /* 注册连接名称 */
- void dbus_connection_close (DBusConnection *connection) /* 关闭连接 */
2.3 信号发送与接收
2.3.1 信号发送
DBUS中信号是一种广播的消息,当发出一个信号,所有连接到 DBUS 总线上并注册了接受对应信号的进程,都会收到该信号。
进程发出一个信号前,需要创建一个 DBusMessage 对象来代表信号,然后追加上一些需要发出的参数,就可以发向总线了。发完之后需要释放消息对象。信号发送的函数声明如程序清单 2‑2所示。- DBusMessage *dbus_message_new_signal (const char *path,
- const char *iface,
- const char *name) /* 创建信号类型消息 */
- void dbus_message_iter_init_append ( DBusMessage *message,
- DBusMessageIter *iter) /* 加入参数到信号 */
- dbus_bool_t dbus_connection_send ( DBusConnection *connection,
- DBusMessage *message,
- dbus_uint32_t *serial) /* 发送信号到总线 */
- void dbus_message_unref (DBusMessage *message) /* 释放消息 */
2.3.2 信号接收
- void dbus_bus_add_match ( DBusConnection *connection,
- const char *rule,
- DBusError *error) /* 告知总线感兴趣的消息 */
- DBusMessage *dbus_connection_pop_message ( DBusConnection *connection) /* 接收消息 */
- dbus_bool_t dbus_message_is_signal (DBusMessage *message,
- const char *iface,
- const char *signal_name) /* 判断消息是否为信号 */
2.4 函数调用和提供函数调用
2.4.1 函数调用
调用一个远程函数与发送一个信号原理类似,需要先创建一个消息(DBusMessage),然后通过注册在 DBUS上的名称指定发送的对象。然后追加相应的参数,调用方法分为两种,一种是阻塞式的,另一种为异步调用。异步调用的时候会得到一个“DBusMessage *” 类型的返回消息,从这个返回消息中可以获取一些返回的参数。
函数调用的函数声明如程序清单 2‑4所示。- DBusMessage *dbus_message_new_method_call (const char *destination,
- const char *path,
- const char *iface,
- const char *method) /* 创建一个函数调用消息 */
- void dbus_message_iter_init_append (DBusMessage *message,
- DBusMessageIter *iter) /* 为消息添加参数 */
- dbus_bool_t dbus_connection_send_with_reply (DBusConnection *connection,
- DBusMessage *message,
- DBusPendingCall **pending_return,
- int timeout_milliseconds) /* 发送消息 */
- void dbus_pending_call_block (DBusPendingCall *pending) /* 阻塞等待返回值 */
- DBusMessage *dbus_pending_call_steal_reply (DBusPendingCall *pending) /* 获得返回消息 */
- dbus_bool_t dbus_message_iter_init (DBusMessage *message,
- DBusMessageIter *iter) /* 获取参数 */
2.4.2 接收函数调用
- void dbus_bus_add_match ( DBusConnection *connection,
- const char *rule,
- DBusError *error) /* 请求获取调用消息 */
- DBusMessage *dbus_connection_pop_message ( DBusConnection *connection) /* 从总线获取消息 */
- dbus_bool_t dbus_message_is_method_call (DBusMessage *message,
- const char *iface,
- const char *method) /* 判定消息是方法调用 */
- dbus_bool_t dbus_message_iter_init (DBusMessage *message,
- DBusMessageIter *iter) /* 获取参数 */
- DBusMessage *dbus_message_new_method_return (DBusMessage *method_call) /* 创建返回消息 */
- void dbus_message_iter_init_append ( DBusMessage *message,
- DBusMessageIter *iter) /* 在消息中填入参数 */
- dbus_bool_t dbus_connection_send ( DBusConnection *connection,
- DBusMessage *message,
- dbus_uint32_t *serial) /* 发送返回消息 */
3. 小结
DBUS是一种高效、易用的进程间通信方式。本文档介绍了DBUS的通信原理,以信号收发和方法调用为框架,介绍了DBUS中常用的函数接口。
DBus分为两种类型:system bus(系统总线),用于系统(Linux)和用户程序之间进行通信和消息的传递;session bus(回话总线),用于桌面(GNOME, KDE等)用户程序之间进行通信。
4. 参考资料
网上看到两篇写的很不错的博客,可以参考学习。
1. http://blog.csdn.net/eastmoon502136/article/details/10044993
2.http://www.cnblogs.com/liyiwen/archive/2012/12/02/2798876.html
原文地址:https://www.cnblogs.com/cxt-janson/p/11428240.html
- Apache Hive-2.3.0 快速搭建与使用
- HBase-1.3.1 集群搭建 - 报错整理
- 分布式唯一ID生成器Twitter 的 Snowflake idworker java版本
- 使用 Phoenix-4.11.0连接 Hbase 集群 ,并使用 JDBC 查询测试
- 高并发分布式系统中生成全局唯一Id汇总
- ZooKeeper 可视化监控 zkui
- 关于RBAC(Role-Base Access Control)的理解
- Spring Boot 中使用 Kafka
- 如何评价一段代码
- java系统高并发的解决方案
- Spring Boot 中使用 Redis
- 使用 Jedis 连接操作 Redis
- 浅析ReDoS的原理与实践
- 使用 Executors,ThreadPoolExecutor,创建线程池,源码分析理解
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- flutter 中监听滑动事件
- 如何通过Cloudera Manager页面自定义图表
- 【-Flutter组件篇- 】1.20新增组件InteractiveViewer
- Android使用SoundPool实现播放音效
- 【- FlutterUnit重大更新 -】Flutter要点集录.md
- Android实现美团外卖底部导航栏动画
- Kudu遇到的问题
- 【 -Flutter自定义组件- 】Wrapper组件,包裹装饰你的一切
- Android Shape属性创建环形进度条
- Ranger同步ldap组问题
- Android系统添加自定义鼠标样式通过按键切换实例详解
- Impala MetaData问题
- 聚焦 Android 11: UI 与 Compose
- 如何给Flutter界面切换实现点特效
- 恢复 RecyclerView 的滚动位置