2011-06-16 26 views
4

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

代码:

# 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后来这个片段:

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应该运行此代码后几次崩溃。但为什么?

+0

我认为这个http://jameswestby.net/weblog/tech/14-caution-python-multiprocessing-and-glib-dont-mix.html可能与我的问题有关 – Sergio 2011-06-17 10:56:17

回答

5

gobject.threads_init()是不够的,您需要拨打dbus.mainloop.glib.threads_init()使dbus-glib线程安全。

+0

不是'gobject'只是一个包装glib,而不是那些'threads_init()',因此*相同的功能*? – Teddy 2013-02-08 00:45:40

2

Service1.py,尝试调用gobject.threads_init()分配dbus_loopDBusGMainLoop()之前。