轉自:https://blog.csdn.net/mr_wangning/article/details/60324291html
DBUS是一種高級的進程間通訊機制。DBUS支持進程間一對一和多對多的對等通訊,在多對多的通信時,須要後臺進程的角色去分轉消息,當一個進程發消息給另一個進程時,先發消息到後臺進程,再經過後臺進程將信息轉發到目的進程。DBUS後臺進程充當着一個路由器的角色。session
DBUS中主要概念爲總線,鏈接到總線的進程可經過總線接收或傳遞消息,總線收到消息時,根據不一樣的消息類型進行不一樣的處理。DBUS中消息分爲四類:架構
1. Methodcall消息:將觸發一個函數調用 ;併發
2. Methodreturn消息:觸發函數調用返回的結果;app
3. Error消息:觸發的函數調用返回一個異常 ;框架
4. Signal消息:通知,能夠看做爲事件消息。異步
1.2 DBUS應用場景
根據DBUS消息類型可知,DBUS提供一種高效的進程間通訊機制,主要用於進程間函數調用以及進程間信號廣播。函數
1 . 函數調用學習
DBUS能夠實現進程間函數調用,進程A發送函數調用的請求(Methodcall消息),通過總線轉發至進程B。進程B將應答函數返回值(Method return消息)或者錯誤消息(Error消息)。ui
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 DBUS通訊原理
如圖 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所示。
程序清單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 信號接收
進程接收信號時,需先告知總線進程感興趣的消息,而後等待接收消息。信號接收函數聲明如程序清單 2‑3所示。
程序清單 2-3 信號接收接口
- 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所示。
程序清單 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 接收函數調用
提供遠程函數調用,首先需告知總線進程感興趣的消息,其次從總線獲取消息並斷定消息是方法調用。而後從消息中獲取參數進行函數執行,最後建立返回消息,併發送消息至總線,由總線轉發至調用的進程。函數聲明如程序清單 2‑5所示。
程序清單 2-5 接收函數調用接口
- 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