2016-01-18 42 views
3

我試圖在幾秒鐘後停止gobject.MainLoop()
我不知道是否有可能爲這種循環設置超時,這將是完美的,但我還沒有找到。如何停止dbus gobject循環

所以,我試着用線程解決這個問題,但不幸的是,主循環阻塞了其他線程。
這裏我的代碼(我使用Python 2.7的工作):

import MediaCenter_dbusConfig 
import dbus 
import gobject 
from dbus.mainloop.glib import DBusGMainLoop 
from time import sleep 
from threading import Thread 


mainloop=0 

class Timeout(Thread): 
    global mainloop 

    def __init__(self): 

     Thread.__init__(self) 

    def run(self): 
     global mainloop 

     i = 0 
     while i < 30: 
      sleep(1) 
      i += 1 
     mainloop.quit() 

class Loop(Thread): 
    global mainloop 

    def __init__(self): 

     Thread.__init__(self) 

    def run(self): 
     global mainloop 

     sleep(5) 
     mainloop.run() 

def catchall_detectedDevicePopUp_from_willShowPopup_signals_handler(popup_string): 
    global mainloop 

    if(popup_string == "DetectedDevicePopUp.qml") : 
     print(popup_string) 
     mainloop.quit() 

def detectedDevicePopUp_detector() : 
    global mainloop 

    dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) 

    bus=MediaCenter_dbusConfig.init() # basicly do a dbus.bus.BusConnection() 

    bus.add_signal_receiver(catchall_detectedDevicePopUp_from_willShowPopup_signals_handler, dbus_interface = "com.orange.mediacenter.apimanager", signal_name = "willShowPopup") 

    mainloop = gobject.MainLoop() 

    thread1 = Timeout() 
    thread2 = Loop() 
    thread1.start() 
    thread2.start() 
    thread1.join() 
    thread2.join() 

在這裏,我呼籲detectedDevicePopUp_detector()。我在等待一個名爲willShowPopup的信號。如果我收到一個信號,我想停止循環並繼續我的程序,並且在30秒之後,如果我沒有收到任何信號,我需要同樣的東西(停止循環並繼續我的程序),但是在這裏它不起作用,我的Timeout線程被我的Loop線程阻塞。
說明:我無法編輯發送的信號(我測試應用程序)。

任何想法?

回答

1

因爲我理解這個問題,線程並不是真的需要。下面是使用gobject.timeout_add添加一段時間後,主循環將運行,如果沒有信號,以阻止它的例子:如果如收到Stop信號

import gobject 
import dbus 
import dbus.service 

from dbus.mainloop.glib import DBusGMainLoop 
DBusGMainLoop(set_as_default=True) 


OPATH = "/com/example/StopLoop" 
IFACE = "com.example.StopLoop" 
BUS_NAME = "com.example.StopLoop" 
TIMEOUT = 30 * 1000 


class Example(dbus.service.Object): 
    def __init__(self, loop): 
     self.loop = loop 
     bus = dbus.SessionBus() 
     bus.request_name(BUS_NAME) 
     bus_name = dbus.service.BusName(BUS_NAME, bus=bus) 
     dbus.service.Object.__init__(self, bus_name, OPATH) 
     # Add a timeout for how long to run mainloop 
     # if no signal is received 
     self.setup_timeout(TIMEOUT) 
     # Listen to the "Stop" signal 
     self.listen_for_signal(bus) 

    def setup_timeout(self, timeout): 
     gobject.timeout_add(timeout, self.handler) 

    def listen_for_signal(self, bus): 
     bus.add_signal_receiver(self.handler, "Stop") 

    def handler(self): 
     # This handler is used for both timeout and signal 
     self.loop.quit() 


if __name__ == "__main__": 
    loop = gobject.MainLoop() 
    a = Example(loop) 
    loop.run() 
    print "Exited mainloop, continuing program..." 

這樣做:

dbus-send --session --type=signal --dest=com.example.StopLoop /com/example/StopLoop com.example.StopLoop.Stop 

主循環將退出,代碼將繼續從那裏loop.run()被調用。

如果沒有收到信號,主循環將停止超時(在這種情況下爲30秒),然後繼續調用loop.run()