【轉載】DBUS及經常使用接口介紹

轉自: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 創建、註冊名稱和關閉鏈接

 

[plain]  view plain  copy
 
  1. DBusConnection  *dbus_bus_get  (DBusBusType  type,  DBusError   *error)             /*  創建和總線的鏈接  */  
  2.   
  3. int  dbus_bus_request_name  (DBusConnection   *connection,  
  4.                              const char         *name,  
  5.                              unsigned int        flags,  
  6.                              DBusError        *error)                                   /*  註冊鏈接名稱      */  
  7.   
  8. void  dbus_connection_close  (DBusConnection  *connection)                           /*  關閉鏈接          */  

 

2.3 信號發送與接收

 

2.3.1 信號發送

    DBUS中信號是一種廣播的消息,當發出一個信號,全部鏈接到 DBUS 總線上並註冊了接受對應信號的進程,都會收到該信號。

    進程發出一個信號前,須要建立一個 DBusMessage 對象來表明信號,而後追加上一些須要發出的參數,就能夠發向總線了。發完以後須要釋放消息對象。信號發送的函數聲明如程序清單 2‑2所示。
程序清單2-2  信號發送接口
[cpp]  view plain  copy
 
  1. DBusMessage  *dbus_message_new_signal  (const  char  *path,  
  2.                                        const  char  *iface,  
  3.                                        const  char  *name)                       /*  建立信號類型消息      */  
  4.   
  5. void  dbus_message_iter_init_append  ( DBusMessage     *message,  
  6.                            DBusMessageIter  *iter)                /*  加入參數到信號        */  
  7.   
  8. dbus_bool_t  dbus_connection_send  ( DBusConnection  *connection,  
  9.                                      DBusMessage    *message,  
  10.                                      dbus_uint32_t    *serial)                       /*  發送信號到總線        */  
  11.   
  12. void  dbus_message_unref  (DBusMessage *message)                                 /*  釋放消息              */  

2.3.2 信號接收

    進程接收信號時,需先告知總線進程感興趣的消息,而後等待接收消息。信號接收函數聲明如程序清單 2‑3所示。
程序清單 2-3 信號接收接口
[cpp]  view plain  copy
 
  1. void  dbus_bus_add_match  ( DBusConnection  *connection,  
  2.                             const char        *rule,  
  3.                             DBusError       *error)                                 /*  告知總線感興趣的消息   */  
  4.   
  5. DBusMessage  *dbus_connection_pop_message  ( DBusConnection  *connection)         /*  接收消息               */  
  6.   
  7. dbus_bool_t  dbus_message_is_signal  (DBusMessage  *message,  
  8.                                       const char      *iface,  
  9.                                       const char     *signal_name)                    /*  判斷消息是否爲信號     */  

2.4 函數調用和提供函數調用

2.4.1 函數調用

     調用一個遠程函數與發送一個信號原理相似,須要先建立一個消息(DBusMessage),而後經過註冊在 DBUS上的名稱指定發送的對象。而後追加相應的參數,調用方法分爲兩種,一種是阻塞式的,另外一種爲異步調用。異步調用的時候會獲得一個「DBusMessage *」 類型的返回消息,從這個返回消息中能夠獲取一些返回的參數。

    函數調用的函數聲明如程序清單 2‑4所示。
程序清單 2-4 函數調用接口
[cpp]  view plain  copy
 
  1. DBusMessage  *dbus_message_new_method_call  (const char  *destination,  
  2.                                              const char  *path,  
  3.                                              const char  *iface,  
  4.                                              const char  *method)                    /*  建立一個函數調用消息    */  
  5.   
  6. void  dbus_message_iter_init_append  (DBusMessage     *message,  
  7.                           DBusMessageIter  *iter)                     /*  爲消息添加參數           */  
  8.   
  9. dbus_bool_t  dbus_connection_send_with_reply  (DBusConnection   *connection,  
  10.                                                DBusMessage      *message,   
  11.                                                DBusPendingCall  **pending_return,  
  12.                                                int            timeout_milliseconds)       /*  發送消息                */  
  13.   
  14. void  dbus_pending_call_block  (DBusPendingCall  *pending)                           /*  阻塞等待返回值           */  
  15.   
  16. DBusMessage  *dbus_pending_call_steal_reply  (DBusPendingCall  *pending)             /*  得到返回消息            */  
  17.     
  18. dbus_bool_t  dbus_message_iter_init  (DBusMessage     *message,  
  19.                           DBusMessageIter  *iter)                     /*  獲取參數                */  

2.4.2 接收函數調用

    提供遠程函數調用,首先需告知總線進程感興趣的消息,其次從總線獲取消息並斷定消息是方法調用。而後從消息中獲取參數進行函數執行,最後建立返回消息,併發送消息至總線,由總線轉發至調用的進程。函數聲明如程序清單 2‑5所示。
程序清單 2-5 接收函數調用接口
[cpp]  view plain  copy
 
  1. void  dbus_bus_add_match  ( DBusConnection  *connection,  
  2.                             const char        *rule,  
  3.                             DBusError       *error)                                   /*  請求獲取調用消息       */  
  4.    
  5. DBusMessage  *dbus_connection_pop_message  ( DBusConnection  *connection)           /*  從總線獲取消息         */  
  6.   
  7. dbus_bool_t  dbus_message_is_method_call (DBusMessage  *message,  
  8.                                           const char     *iface,  
  9.                                           const char     *method)                       /*  斷定消息是方法調用     */  
  10.     
  11. dbus_bool_t  dbus_message_iter_init  (DBusMessage     *message,  
  12.                           DBusMessageIter  *iter)                    /*  獲取參數               */  
  13.   
  14. DBusMessage  *dbus_message_new_method_return  (DBusMessage *method_call)            /*  建立返回消息           */  
  15.   
  16. void  dbus_message_iter_init_append  ( DBusMessage     *message,  
  17.                            DBusMessageIter  *iter)                   /*  在消息中填入參數       */  
  18.   
  19. dbus_bool_t  dbus_connection_send  ( DBusConnection   *connection,  
  20.                                      DBusMessage     *message,  
  21.                                      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

相關文章
相關標籤/搜索