如何停止dbus gobject循环 [英] How to stop a dbus gobject loop

查看:152
本文介绍了如何停止dbus gobject循环的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I try to stop a gobject.MainLoop() after a few seconds.
I don't know if it's possible to set a timeout to this kind of loop, it would be perfect but I have not found that.

因此,我尝试通过线程解决此问题,但不幸的是,主循环阻止了其他线程.
这是我的代码(我正在使用python 2.7):

So, I tried to workaround this with threading but unfortunately, the main loop block others threads.
Here my code (I'm working with 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线程阻塞.
澄清:我无法编辑发送的信号(我正在测试应用程序).

Here I call detectedDevicePopUp_detector(). I'm waiting for a signal named willShowPopup. If I received a signal, I want to stop the loop and continue my program, and after 30s, if I have not received any signal, I want the same thing (stop the loop and continue my program) but here it doesn't work, my Timeout thread is blocked by my Loop thread.
Clarification: I can not edit the signals sent (I test an application).

有什么想法吗?

推荐答案

据我了解的问题,实际上并不需要线程.下面是一个使用gobject.timeout_add来添加主循环的最大时间的示例,如果没有信号可以停止它,则该循环将运行:

As I understood the question, threading is not really wanted. Below is an example that uses gobject.timeout_add to add a maximum time that the mainloop will run if there is no signal to stop it:

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信号,例如通过这样做:

If the Stop signal is received e.g. by doing:

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

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

The mainloop will exit and the code will continue from where loop.run() was called.

如果未收到信号,则主循环将在超时(在这种情况下为30秒)之前停止,并从调用loop.run()的位置继续.

If no signal is received the mainloop will be stopped by the timeout (30 seconds in this case) and continue from where loop.run() was called.

这篇关于如何停止dbus gobject循环的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆