python gobject.mainloop gobbles信号事件



我有一个模块,该模块使用python"螺纹"进行并发,而"信号"用于关闭挂钩:

signal.signal(signal.SIGINT, self.shutdownhook)

我有另一个使用dbus和gobject

的模块
dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
....
GObject.threads_init()
mainloop = GObject.MainLoop()
mainloop.run()

当我单独运行它们时,它们都按预期运行,ctrl+c通过"键盘插发"导致终止。

但是,当我将它们一起运行时,Mainloop终止,但是关闭挂钩从未被调用 - 如果没有kill -9 pid

有人可以解释为什么会发生这种情况,以及如何最好地整合两个模型

这是一个工作示例,突出了我的问题。我不能仅使用CTRL C退出程序,在这种情况下也没有调用关闭挂钩。

import threading
import signal
import sys
from gi.repository import GObject

def runMainloop():
        print('running mainloop')
        mainloop.run()
def shutdown():
        print('shutdown')
def readInput():
        print('readInput')
        print(sys.stdin.readline())
if __name__ == '__main__':
        signal.signal(signal.SIGINT, shutdown)
        signal.signal(signal.SIGTERM, shutdown)
        GObject.threads_init()
        mainloop = GObject.MainLoop()
        mainloopThread = threading.Thread(name='mainloop', target=runMainloop)
        mainloopThread.setDaemon(True)
        mainloopThread.start()
        print('started')
        inputThread = threading.Thread(name='input', target=readInput)
        inputThread.start()
        print('started input')

没人感兴趣,所以让我尝试。

只是在同一页面上:

import signal
from gi.repository import GObject
GObject.threads_init()
mainloop = GObject.MainLoop()
signal.signal(signal.SIGINT, lambda n, f: mainloop.quit())
mainloop.run()

此代码有效:

import signal
from gi.repository import GObject
signal.signal(signal.SIGINT, lambda n, f: print("kill"))
GObject.threads_init()
mainloop = GObject.MainLoop()
mainloop.run()

我首先注册了信号处理程序,然后启动循环。奇怪的是,它没有被称为。但是结果是 - 如预期...

作为旁注 - 根据他们的文档... mainloop被弃用。那是第一件事。

编辑

这是MainLoop中的stdin阅读的示例:

import signal
import sys
from gi.repository import GObject, GLib
GObject.threads_init()
def readInput():
    print('readInputn')
    while True:
        input = sys.stdin.readline()
        print(input)
        if input.strip() == 'exit':
            print('closing main loop')
            mainloop.quit()
            print('terminating thread')
            return
if __name__ == '__main__':
    signal.signal(signal.SIGINT, signal.SIG_DFL)
    mainloop = GObject.MainLoop.new(None, False)
    GObject.timeout_add(1000, readInput)
    # inputThread = threading.Thread(name='input', target=readInput)
    # inputThread.start()
    # print('started input')
    print('running mainloopn')
    try:
        mainloop.run()
    except KeyboardInterrupt:
        mainloop.quit()

添加.new(None, False)允许CTRL-C正常工作。从这里拿走了它,这也是另一个有关将脉冲音频控制器与GLib/GObject循环集成的线程。有关于与循环集成DBU的样本,但我不确定您想走哪种方式...

添加计时器使循环接收unix信号。

import gi
from gi.repository import GLib
import signal
GLib.threads_init()
mainloop = GLib.MainLoop()
signal.signal(signal.SIGTERM, lambda signum, frame: mainloop.quit())
GLib.timeout_add(1000, lambda *args: (print("tick") or True))
try:
    mainloop.run()
except KeyboardInterrupt:
    print()

最新更新