Dbus/GLib主循环,背景线程

Dbus/GLib主循环,背景线程

问题描述:

我开始使用DBus和事件驱动编程。我试图创建的服务实际上由三部分组成,但两部分实际上是“服务器”的东西。Dbus/GLib主循环,背景线程

1)实际的DBus服务器通过HTTPS与远程网站通话,管理会话并向客户端传递信息。

2)服务的其他部分调用保活页每2分钟保持会话处于活动状态的外部网站

3)客户做出的服务调用来检索服务信息上。

我发现了一些简单的示例程序。我试图将它们适应原型#1和#2。而不是为两者建立单独的程序。我以为我可以在一个单一的,两个线程的过程中运行它们。

我看到的问题是我在我的保持活动线程中调用time.sleep(X)。线程进入睡眠状态,但不会醒来。我认为GIL不是由GLib主循环释放的。

这里是我的线程代码:

class Keepalive(threading.Thread): 
    def __init__(self, interval=60): 
    super(Keepalive, self).__init__() 
    self.interval = interval 
    bus = dbus.SessionBus() 
    self.remote = bus.get_object("com.example.SampleService", "/SomeObject") 

    def run(self): 
    while True: 
     print('sleep %i' % self.interval) 
     time.sleep(self.interval) 
     print('sleep done') 
     reply_status = self.remote.keepalive() 
     if reply_status: 
      print('Keepalive: Success') 
     else: 
      print('Keepalive: Failure') 

从打印语句,我知道,睡眠开始,但我从来没有看到“睡眠来完成。”

下面是主要代码:

if __name__ == '__main__': 
try: 
    dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) 

    session_bus = dbus.SessionBus() 
    name = dbus.service.BusName("com.example.SampleService", session_bus) 
    object = SomeObject(session_bus, '/SomeObject') 

    mainloop = gobject.MainLoop() 

    ka = Keepalive(15) 
    ka.start() 
    print('Begin main loop') 
    mainloop.run() 
except Exception as e: 
    print(e) 
finally: 
    ka.join() 

其他一些意见:

我看到“开始主循环”的消息,所以我知道它越来越控制。然后,我看到“睡眠%i”,然后,什么也没有。

如果我^ C,那么我看到“睡眠完成”。约20秒钟后,我从self.run异常(),远程应用程序没有响应:

DBusException:org.freedesktop.DBus.Error.NoReply:未收到回复。可能的原因包括:远程应用程序未发送回复,消息总线安全策略阻止回复,回复超时过期或网络连接中断。

在服务器中运行我的存活代码的最佳方式是什么?

感谢,

你必须使用gobject通过调用gobject.threads_init()时明确启用多线程。有关背景信息,请参阅PyGTK FAQ

除此之外,出于您所描述的目的,超时似乎更适合。使用方法如下:

# Enable timer 
self.timer = gobject.timeout_add(time_in_ms, self.remote.keepalive) 
# Disable timer 
gobject.source_remove(self.timer) 

这将调用keepalive功能每time_in_ms(毫)秒。更多的细节可以在PyGTK reference找到。

+0

Jro,谢谢你的建议。我是新来的,真的不明白dbus/glib/gtk/gobject之间的关系。 tomeout_add()正是我想要的。 – fandingo