如何停止 dbus gobject 循环
How to stop a dbus gobject loop
我尝试在几秒钟后停止 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
线程阻塞。
澄清:我无法编辑发送的信号(我测试了一个应用程序)。
有什么想法吗?
根据我的理解,线程并不是真正需要的。下面是一个示例,它使用 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()
的地方继续。
我尝试在几秒钟后停止 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
线程阻塞。
澄清:我无法编辑发送的信号(我测试了一个应用程序)。
有什么想法吗?
根据我的理解,线程并不是真正需要的。下面是一个示例,它使用 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()
的地方继续。