分享

dbus关于公共名和唯一名

 昵称5169677 2016-08-09

在CSDN看到fmddlmyy写的关于DBUS的系列文章,下面是自己的一些心得体会。(fmddlmyy博客地址:http://blog.csdn.net/fmddlmyy/article/details/3585730)

这篇文章扩展的只有下面几句话:

  1. 每个连接都有一个唯一名(unique-name);

  2. 每个连接可以拥有一个公共名(well-known names);

  3. 多个应用程序想拥有公共名时,可能会出现排队等待的情况;

DBUS中有公共名唯一名的概念,唯一名就是一个应用程序连接到bus 守护进程的时候,bus会自动给这个应用程序一个  唯一连接名(unique connection

name)。这个连接名以“:”开头,由数字组成,每一个连接到bus守护进程的应用程序都会有一个唯一的这个名字,不可能重复,比如连接的唯一名可能为   ":1.81"  。当

一个应用程序有了这个连接名之后我们,称这个程序“拥有了这个名字”。但是一个连接还可以拥有一个公共名(well-known names),所谓的公共名就是它可以被任何连

接使用,而且这个公共名下面提供一些众所周知的服务,方法。刚才说过一个连接可以拥有一个名字,但是如果多个连接想拥有一个公共名呢,那么bus守护进程是如何处

理的,bus的总原则是:一个公共名在任何时刻只能被一个连接所拥有,当有多个连接想拥有一个公共名时,bus进程会将这些连接放到一个排队列表中,等待当前拥有者释放了这个公共名,然后才让列表中的一个连接拥有这个公共名

看第一个例子:

NO1: 获得一个唯一名

 


#include <stdio.h> #include <dbus/dbus.h> #include <dbus/dbus-glib.h> int main () { DBusConnection *connection; DBusError error; char *uniquename; /* 初始化 */ dbus_error_init (&error); /* 连接到会话总线 */ connection = dbus_bus_get (DBUS_BUS_SESSION,&error); /* 判断是否出错 */ if (dbus_error_is_set (&error)) { printf ("error\n"); dbus_error_free (&error); return 1; } /* 获得这个连接的唯一名 */ uniquename = dbus_bus_get_unique_name (connection); printf ("unuqiename ->%s\n",uniquename); return 0; }

 编译运行:

# gcc bus11.c  `pkg-config --cflags --libs dbus-glib-1` -o bus11

#./bus11

结果:

unuqiename  ->:1.154

代码比较简单,有点要注意:dbus_error_init (&error);这句话必须要加上,不然在运行的时候会出现如下错误:

process 9656: arguments to internal_bus_get() were incorrect, assertion "(error) == NULL || !dbus_error_is_set ((error))" failed in file dbus-bus.c line 435. This is normally a bug in some application using the D-Bus library. D-Bus not built with -rdynamic so unable to print a backtrace 已放弃 (core dumped)

 

 

NO2:获得公共名

在上面代码做如下修改,


#include <stdio.h> #include <dbus/dbus.h> #include <dbus/dbus-glib.h> int main () { DBusConnection *connection; DBusError error; char *uniquename; /* 初始化 */ dbus_error_init (&error); /* 连接到会话总线 */ connection = dbus_bus_get (DBUS_BUS_SESSION,&error); /* 判断是否出错 */ if (dbus_error_is_set (&error)) { printf ("error\n"); dbus_error_free (&error); return 1; } /* 获得这个连接的唯一名 */ uniquename = dbus_bus_get_unique_name (connection); printf ("unuqiename :%s\n",uniquename); /*================= 添加的代码 =================*/ /* 想bus进程请求让我这个连接还拥有一个公共名 */ dbus_bus_request_name (connection,"kjskjdf.sdkfja.kdkdkd",0,&error); sleep (20); return 0; }

 

 

上面用到函数 dbus_bus_request_name(),它的原型如下:

 

DBUS_EXPORT int dbus_bus_request_name ( DBusConnection * connection, const char * name, unsigned int flags, DBusError * error )

 

第一个参数是你的连接,第二个参数你要请求给这个连接的公共名,第三个是标志位(比较重要的一个标志位),第四个错误参数。

这个函数的作用是让bus进程分配一个我指定的公共名给我。同样编译运行改运行程序,通过d-feet程序查看bus的相关信息:


我们看到,你只指定的公共名确实申请成功,而且它也有一个唯一名和公共名。

 NO3:做个实验,我们将bus11.c拷贝一份,命名为bus22.c,编译bus22.c程序。

按照下面步骤运行:

  a. 先运行bu11.c程序,./bus11

  b. 再开一个终端运行bus22.c程序,./bus22

  c. 通过d-feet查看有什么结果。

疑问:

  因为两个程序都是请求同一 公共名,但是dbus在同一时刻只能让一个连接获得这个公共名,那么是bus22获得还是bus11获得?

通过d-feet程序看出,bus11获得了这个公共名,而bus22在bus11睡眠10秒钟后才获得这个公共名。


 uniquename每次都不一样的。10秒中之后,bus1退出之后,bus22再获得这个公共名,如下图:


结论:一个时刻,公共名只能被一个连接所拥有。 

那有没有办法实现bus22不等待,直接替换掉这个公共名的拥有者呢?  办法有!这就涉及到函数dbus_bus_request_name()的第三个参数flag,标志位参数。它的值有下面3种情况:


1. DBUS_NAME_FLAG_ALLOW_REPLACEMENT 2. DBUS_NAME_FLAG_DO_NOT_QUEUE 3. DBUS_NAME_FLAG_REPLACE_EXISTING

下面用A和B分别代表上面的bus11和bus22程序,上面的公共名‘kjskjdf.sdkfja.kdkdkd’用NAME代替,下面解释上面各个参数的意思:


第一种:如果A当前拥有了NAME,而且指定falg为DBUS_NAME_FLAG_ALLOW_REPLACEMENT,那么当B代替A拥有NAME时,B中flag必须指定DBUS_NAME_FLAG_REPLACE_EXISTING 第二种:如果A当前拥有了NAME,此时A的flag可以指定也可以为0,那么当B想代替A拥有NAME,但是它的flag指定为DBUS_NAME_FLAG_DO_NOT_QUEUE的时候,表示B不想排队等待A结束,因为此时B此刻只想成为NAME 的拥有者。 第三种:如果A当前拥有了NAME,而此时A的flag指定为0,那么当B想代替A拥有NAME,同时它的flag指定为DBUS_NAME_FLAG_REPLACE_EXISTING时,这种情 况和B的flag指定为0的结果是相同的,就是B等待A的结束,再拥有NAME;但是如果A的flag指定为DBUS_NAME_FLAG_ALLOW_REPLACEMENT,那么B可以直接将 A踢开,直接拥有NAME。DBUS_NAME_FLAG_REPLACE_EXISTING是一个相对温柔的一个标志~~~~。

 

 

 所以如果想实现刚才说的让bus22替换掉bus11,实现方法很简单,让bus11.c中的dbus_bus_request_name()第三个参数DBUS_NAME_FLAG_ALLOW_REPLACEME

NT,bus22.c中的dbus_bus_request_name()第三个参数为DBUS_NAME_FLAG_REPLACE_EXISTING。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多