如何同时监听 D-Bus 事件和 IPC 通道?

Posted

技术标签:

【中文标题】如何同时监听 D-Bus 事件和 IPC 通道?【英文标题】:How to listen to D-Bus events and the IPC channel at the same time? 【发布时间】:2017-04-04 03:10:27 【问题描述】:

我有以下简化的代码。它监听 D-Bus 并在创建新作业时执行某些操作。为此,我需要启动 GLib.MainLoop().run(),因为我发现了多个示例。

在执行此操作时,我希望程序持续侦听 IPC 总线并在收到消息时执行某些操作。但显然这不起作用,因为我的程序卡在GLib.MainLoop().run()

如何实现让我同时听 D-Bus 和 IPC 的东西?

#!/usr/bin/env python3.4
import asgi_ipc as asgi
from gi.repository import GLib
from pydbus import SystemBus
from systemd.daemon import notify as sd_notify

def main():
    bus = SystemBus()
    systemd = bus.get(".systemd1")
    systemd.onJobNew = do_something_with_job()

    channel_layer = asgi.IPCChannelLayer(prefix="endercp")

    # Notify systemd this unit is ready
    sd_notify("READY=1")

    GLib.MainLoop().run()

    while True:
        message = channel_layer.receive(["endercp"])
        if message is not (None, None):
            do_something_with_message(message)


if __name__ == "__main__":
    # Notify systemd this unit is starting
    sd_notify("STARTING=1")

    main()

    # Notify systemd this unit is stopping
    sd_notify("STOPPING=1")

【问题讨论】:

【参考方案1】:

由于IPCChannelLayer.receive() 不会阻塞,您可以在空闲回调中运行它。试试这个:

callback_id = GLib.idle_add(GLib.PRIORITY_DEFAULT_IDLE, poll_channel, data=channel_layer)
GLib.MainLoop().run()
GLib.idle_remove_by_data(channel_layer)

# ...

def poll_channel(channel_layer):
    message = channel_layer.receive(["endercp"])
    if message is not (None, None):
        do_something_with_message(message)
    return GLib.SOURCE_CONTINUE

【讨论】:

以上是关于如何同时监听 D-Bus 事件和 IPC 通道?的主要内容,如果未能解决你的问题,请参考以下文章

IPC进程间通信 D-Bus(Desktop Bus)快速入门(以libdbus-glib库为例)

Qt高级——D-Bus快速入门

编译rv1.8 app/dbserve时报错:No package ‘dbus-1‘ found(D-Bus是什么?)(如何安装和使用D-Bus?)(缺少librkdb.so)

关于事件监听的那些事

dbus和qtdbus

dbus和qtdbus