2011-06-16 51 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()之前。