在线程内调用 dbus-python

Posted

技术标签:

【中文标题】在线程内调用 dbus-python【英文标题】:Calling dbus-python inside a thread 【发布时间】:2011-09-16 19:08:48 【问题描述】:

在线程中调用 dbus 方法时出现段错误。这是我的场景:我有一个公开方法测试的程序 Service1。第二个程序Service2 公开了一个方法expose。由于此方法进行了一些严肃的数值计算,我将一些参数从暴露传递给正在运行的线程阅读器。反过来,该线程在结束其工作时调用 Service1 的方法 test。我在上次 dbus 调用中遇到了段错误。

代码:

# Service1.py
class Service1(Object):
    def __init__(self, bus):
        name = BusName('com.example.Service1', bus)
        path = '/'
       super(Service1, self).__init__(name, path)

    @method(dbus_interface='com.example.Service1',
        in_signature='s', out_signature='s')
    def test(self, test):
        print 'test being called'
        return test

dbus_loop = DBusGMainLoop()
dsession = SessionBus(mainloop=dbus_loop)
loop = gobject.MainLoop()
gobject.threads_init()

im = Service1(dsession)
loop.run()


# Service2.py
dbus_loop = DBusGMainLoop()
dsession = SessionBus(mainloop=dbus_loop)

class Service2(Object):
def __init__(self, bus):
    name = BusName('com.example.Service2', bus)
    super(Service2, self).__init__(name, '/')

    self.queue = Queue()
    self.db = bus.get_object('com.example.Service1', '/')
    self.dbi = dbus.Interface(self.db, dbus_interface='com.example.Service1')

@method(dbus_interface='com.example.Service2',
        in_signature='', out_signature='')
def expose(self):
    print 'calling expose'
    self.queue.put(('params',))

def reader(self):
    while True:
        val = self.queue.get()
        dd = self.dbi.test('test')
        print dd
        self.queue.task_done()


gobject.threads_init()
loop = gobject.MainLoop()

im = Service2(dsession)
reader = threading.Thread(target=im.reader)
reader.start()

loop.run()

要测试,运行 Service1.py、Service2.py 和稍后这个 sn-p:

dbus_loop = DBusGMainLoop()
session = SessionBus(mainloop=dbus_loop)
proxy = session.get_object('com.example.Service2', '/')
test_i = dbus.Interface(proxy, dbus_interface='com.example.Service2')
test_i.expose()

Service2.py 应该在运行此代码几次后崩溃。但为什么呢?

【问题讨论】:

我认为这个jameswestby.net/weblog/tech/… 可能与我的问题有关 【参考方案1】:

gobject.threads_init() 还不够,你需要调用dbus.mainloop.glib.threads_init() 使 dbus-glib 线程安全。

【讨论】:

gobject 不只是 glib 的一个包装器,那些 threads_init() 不是因此 相同的功能【参考方案2】:

Service1.py 中,尝试调用gobject.threads_init() 之前dbus_loop 分配给DBusGMainLoop()

【讨论】:

以上是关于在线程内调用 dbus-python的主要内容,如果未能解决你的问题,请参考以下文章

在线程内调用 dbus-python

CountDownTimer:“无法在未调用 Looper.prepare() 的线程内创建处理程序”

无法在未调用 Looper 准备的线程内创建处理程序 [重复]

sys.exit()在Python多线程内调用时不会退出

无法在未调用 Looper 的线程内创建处理程序 [重复]

无法在未调用 Looper.prepare()3 的线程内创建处理程序