2016-11-20 26 views
4

我有以下簡單的代碼。它聽取D-Bus並在創建新工作時做一些事情。爲了實現這個目標,我需要啓動GLib.MainLoop().run(),因爲我發現了多個示例。如何同時收聽D-Bus事件和IPC頻道?

雖然這樣做,我希望程序不斷收聽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") 

回答

2

由於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