多线程调用DBUS服务注意事项

多线调用DBUS服务注意事项

转载时请注明出处和作者联系方式
作者联系方式:李先静 <xianjimli at hotmail dot com>

1.多线程初始化,特别不要忘记调用dbus_g_thread_init。

  1. g_type_init();
  2. g_thread_init(NULL);
  3. dbus_g_thread_init();

2.确保不同线程使用不同的DBusConnection。DBUS提供了函数dbus_bus_get_private用于获取独立的DBusConnection,但dbus-glib并没有提供相应的函数,我们自己可以封装一个。

  1. static inline
  2. DBusGConnection* dbus_g_bus_get_private (DBusBusType     type,
  3.                 GMainContext* main_context,
  4.                 GError    **error)
  5. {
  6.     DBusConnection *connection = NULL;
  7.     DBusError derror = {0};
  8.  
  9.     g_return_val_if_fail (error == NULL || *error == NULL, NULL);
  10.  
  11.     //XXX:make sure this function is called in main thread by calling dbus_g_bus_get
  12.     //_dbus_g_value_types_init ();
  13.  
  14.     dbus_error_init (&derror);
  15.  
  16.     connection = dbus_bus_get_private (type, &derror);
  17.     if (connection == NULL)
  18.     {
  19.         dbus_set_g_error (error, &derror);
  20.         dbus_error_free (&derror);
  21.         return NULL;
  22.     }
  23.  
  24.     /* does nothing if it's already been done */
  25.     dbus_connection_setup_with_g_main (connection, main_context);
  26.  
  27.     return DBUS_G_CONNECTION_FROM_CONNECTION (connection);
  28. }


3.确保不同线程调用相同服务时不会使用同一个DBusProxy。如果使用了单实例,用下列方式让每个线程有独立的实例。
  1. EventManager* event_manager_get_default(void)
  2. {
  3.     static __thread EventManager* event_manager = NULL;
  4.  
  5.     if(event_manager == NULL)
  6.     {
  7.         event_manager = event_manager_create();
  8.     }
  9.  
  10.     return event_manager;
  11. }

__thread是C99中新增的,用于线程局部存储的编译指令,这里它让每个线程访问不同的实例。

4.如果在非主线程调用异步函数或者接收事件,一定要有自己的GMainLoop和GMainContext,并用下列函数与DBusConnection关联。

  1. dbus_connection_setup_with_g_main (connection, main_context);

~~the end~~

原文地址:https://www.cnblogs.com/zhangyunlin/p/6167611.html