python - Dbus/GLib 主循环,后台线程

标签 python glib dbus

我一般从 DBus 和事件驱动编程开始。我尝试创建的服务实际上由三部分组成,但有两部分是真正的“服务器”部分。

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

2) 服务的另一部分每 2 分钟调用一次保持事件页面,以保持 session 在外部网站上处于事件状态

3) 客户端调用服务以从服务中检索信息。

我找到了一些简单的示例程序。我正在尝试使它们适应原型(prototype) #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')

从打印语句中,我知道 sleep 开始了,但我从未看到“ sleep 完成”。

主要代码如下:

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()

一些其他观察:

我看到“开始主循环”消息,所以我知道它正在获得控制权。然后,我看到“sleep %i”,之后什么也没有。

如果我 ^C,那么我会看到“sleep done”。大约 20 秒后,我从 self.run() 得到一个异常,远程应用程序没有响应:

DBusException: org.freedesktop.DBus.Error.NoReply: Did not receive a reply. Possible causes include: the remote application did not send a reply, the message bus security policy blocked the reply, the reply timeout expired, or the network connection was broken.

在服务器中运行保持事件代码的最佳方式是什么?

谢谢,

最佳答案

在使用 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)

这会每隔 time_in_ms(毫)秒调用一次 keepalive 函数。同样,可以在 PyGTK reference 找到更多详细信息。 .

关于python - Dbus/GLib 主循环,后台线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7741035/

相关文章:

python - BlueZ DBUS API - GATT 接口(interface)对 BLE 设备不可用

linux - 配置 make gnome commander - no glib 2.6.0

python - 所有列表值都相同

python - 替换 pandas 数据框中的 nan

python - 如何区分emacs中关键字 "import" "def"和 "try"的颜色?

linux - 如何摆脱 'GLIBCXX_3.4.9 not found error' ?

c - Vala构建共享库时是否存在内存泄漏?

java - 使用 dbus 调用 java 方法

linux - 我如何从返回字节数组的 dbus bluez api 中提取任何有用的信息

Python serial - 尝试使用未打开的端口