【问题标题】:How to stop a dbus gobject loop如何停止 dbus gobject 循环
【发布时间】:2016-04-23 09:49:01
【问题描述】:

我尝试在几秒钟后停止gobject.MainLoop()
我不知道是否可以为这种循环设置超时,这将是完美的但我没有发现。

所以,我尝试使用线程来解决这个问题,但不幸的是,主循环阻塞了其他线程。
这是我的代码(我正在使用 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 线程阻塞了。
澄清:我无法编辑发送的信号(我测试应用程序)。

有什么想法吗?

【问题讨论】:

    标签: python multithreading python-2.7 dbus gobject


    【解决方案1】:

    据我了解,线程并不是真正需要的。下面是一个示例,它使用gobject.timeout_add 来添加主循环在没有信号停止时将运行的最长时间:

    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..."
    

    如果收到Stop 信号,例如通过这样做:

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

    主循环将退出,代码将从调用 loop.run() 的位置继续。

    如果没有收到信号,主循环将在超时(本例中为 30 秒)停止并从调用 loop.run() 的位置继续。

    【讨论】:

      猜你喜欢
      • 2018-05-13
      • 1970-01-01
      • 2022-01-11
      • 2014-05-30
      • 2010-09-26
      • 2012-06-19
      • 2019-07-01
      • 2013-09-11
      • 2012-11-29
      相关资源
      最近更新 更多