0

我使用以下代码创建了 dbus 服务器,将其命名为 server1.py

#!/usr/bin/python2.7
import dbus.service
import dbus.glib
import glib
import gobject
from dbus.mainloop.glib import DBusGMainLoop


class APP_Server(dbus.service.Object):
    def __init__(self):
        bus = dbus.SessionBus(private = True, mainloop = DBusGMainLoop())
        bus_name = dbus.service.BusName('de.test.app1', bus)
        dbus.service.Object.__init__(self, bus_name, '/de/test/app1_obj_path')

    @dbus.service.method("test.app1.interface",)
    def is_ready(self):           
        return True

def publish_dbus():
    loop = glib.MainLoop()
    APP_Server()
    loop.run()

if __name__ == '__main__': 
    gobject.threads_init()
    dbus.glib.init_threads()
    publish_dbus()

然后我想通过以下代码访问 server1.py 中的 dbus 服务,将其命名为 server2.py,它也将用作 dbus 服务器。

#!/usr/bin/python2.7
import dbus.service
import dbus.glib
import glib
import dbus.mainloop
import gobject
from dbus.mainloop.glib import DBusGMainLoop
from threading import Thread
from time import sleep


class APP_Server(dbus.service.Object):
    def __init__(self):
        bus = dbus.SessionBus(private = True, mainloop = DBusGMainLoop())
        bus_name = dbus.service.BusName('de.test.app3', bus)
        dbus.service.Object.__init__(self, bus_name, '/de/test/app3_obj_path')

    @dbus.service.method("test.app3.interface",)
    def is_ready(self):           
        return True

def call_dbus():
    bus_name = 'de.test.app1'
    obj_path = '/de/test/app1_obj_path'
    interface_name = 'test.app1.interface'
    count = 1
    while count < 1000:
        proxy_bus = dbus.SessionBus(private = True)
        obj = None
        try:
            obj = proxy_bus.get_object(bus_name, obj_path)
        except:
            sleep(1)
            obj = proxy_bus.get_object(bus_name, obj_path)
        ready = obj.get_dbus_method('is_ready', interface_name)
        ready(pid_, bin_path)
        count += 1
        print count 

def publish_dbus():
    loop = glib.MainLoop()
    APP_Server()
    loop.run()

if __name__ == '__main__':
    gobject.threads_init()
    dbus.glib.init_threads()
    th1 = Thread(target = publish_dbus)
    th1.start()
    th2 = Thread(target = call_dbus)
    th2.start()
    sleep(10000000)

然后在运行 server2.py 之后,应用程序将在线程“call_dbus”中没有完成所有 dbus 调用而终止。

如果我尝试使用以下代码,只需将 server2.py 中的代码更改如下:

从:

 proxy_bus = dbus.SessionBus(private = True)

至:

  proxy_bus = dbus.SessionBus(private = True, mainloop = dbus.mainloop.NULL_MAIN_LOOP)

现在,通过使用工具“d-feet”,线程“callbus”完成后将有许多连接,该工具可用作d-bus调试器来检查dbus服务器是否准备好或dbus连接是否已建立。

如果有人可以提出一些建议使其正常工作?

4

1 回答 1

2

我注意到的是:

  • 您的总线/对象名称不匹配。
  • 每次在 while 循环中创建一个新的 dbus 连接。非常糟糕的主意,特别看到你没有关闭它们。
    将调用移出循环,或使用共享连接 ( private=False)
  • 您实际上并不需要一个自己的线程来发布 dbus 对象,这就是 mainloop 的用途。
  • 如果您在不同的线程中运行主循环,请确保您有办法停止,否则kill将是终止程序的唯一方法。或者把 int 放在你的主线程中,那么它至少应该对Ctrl-C
  • 程序结束时的睡眠是不必要的。只要程序周围有正在运行的非守护线程,就不会退出。

将所有这些放在一起,这应该可以工作:

#!/usr/bin/python2.7
import dbus.service
import dbus.glib
import glib
import dbus.mainloop
import gobject
from dbus.mainloop.glib import DBusGMainLoop
from threading import Thread
from time import sleep


class APP_Server(dbus.service.Object):
    def __init__(self):
        bus = dbus.SessionBus(private = True, mainloop = DBusGMainLoop())
        bus_name = dbus.service.BusName('de.test.app3', bus)
        dbus.service.Object.__init__(self, bus_name, '/de/test/app3_obj_path')

    @dbus.service.method("test.app3.interface",)
    def is_ready(self):           
        return True

def call_dbus():
    bus_name = 'de.test.app3'
    obj_path = '/de/test/app3_obj_path'
    interface_name = 'test.app3.interface'
    proxy_bus = dbus.SessionBus(private = True)
    count = 1
    while count < 1000:
        obj = None
        try:
            obj = proxy_bus.get_object(bus_name, obj_path)
        except:
            sleep(1)
            obj = proxy_bus.get_object(bus_name, obj_path)
        ready = obj.get_dbus_method('is_ready', interface_name)
        #ready(pid_, bin_path)
        count += 1
        print count 


if __name__ == '__main__':
    gobject.threads_init()
    dbus.glib.init_threads()
    loop = glib.MainLoop()
    server = APP_Server()
    #th1 = Thread(target = publish_dbus)
    #th1.start()
    th2 = Thread(target = call_dbus)
    th2.start()
    loop.run()
于 2013-04-25T10:16:08.253 回答