4

我目前正在尝试创建一个 python 脚本,它必须使用 GObject.MainLoop() 与蓝牙客户端进行通信。我将循环放在一个新线程中,以免阻塞剩余的代码。

一切正常,直到我尝试使用 Control + C 退出程序。如果我点击此命令,第二个 try and catch 块(“Host:...”)似乎没有被执行。

示例脚本:

import time
import threading

from dbus.mainloop.glib import DBusGMainLoop

try:
    from gi.repository import GObject
except ImportError:
    import gobject as GObject

DBusGMainLoop(set_as_default=True)

def myThread(a):
    try:
        GObject.threads_init()
        mainloop = GObject.MainLoop()
        mainloop.run()

    except KeyboardInterrupt:
        mainloop.quit()
        print("Thread: KeyboardInterrupt")
    return

try:
    myT = threading.Thread(target=myThread, args=(1,))
    myT.start()

    while 1:
        print("Host: Print every 1 sec")
        time.sleep(1)
except KeyboardInterrupt:
    print("Host: KeyboardInterrupt")

脚本的输出:

Host: Print every 1 sec
Host: Print every 1 sec
^CHost: Print every 1 sec
Thread: KeyboardInterrupt
/usr/lib/python2.7/dist-packages/gi/types.py:113: Warning: Source ID 1 was not found when attempting to remove it
  return info.invoke(*args, **kwargs)
Host: Print every 1 sec
Host: Print every 1 sec
Host: Print every 1 sec
Host: Print every 1 sec

Process finished with exit code -1

现在我想知道为什么“print(”Host:KeyboardInterrupt“)”没有被执行。此外,我不确定如何解决所述警告。

希望你能帮忙!

4

1 回答 1

4

事实上,我能够自己解决问题。

您只需将 MainLoop() 放在主线程中,然后在新线程 (myT) 中启动当前执行“print("Host: Print every 1 sec")”的其他操作。所以你必须从上面的代码中改变线程。然后,如果发生 KeyboardInterrupt,您必须手动退出第二个线程 (myT)。

只调用“print("Thread: KeyboardInterrupt")”的原因是,如果您使用 MainLoop,调用它的进程将被视为“新的主线程”。

但是,我仍然不确定如何摆脱错误:

(process:2429): GLib-CRITICAL **: Source ID 1 was not found when attempting to remove it

根据帖子“ GLib-CRITICAL **: Source ID XXX was not found when trying to remove it ” 警告不是问题,所以我将忽略它。希望这可以帮助任何偶然发现这篇文章的人!

例子:

import time
import threading

from dbus.mainloop.glib import DBusGMainLoop

try:
    from gi.repository import GObject
except ImportError:
    import gobject as GObject

DBusGMainLoop(set_as_default=True)

def myThread(run_event):
    while run_event.is_set():
        print("Thread: Print every 1 sec")
        time.sleep(1)
    print("Thread: Exit")
    return

try:
    run_event = threading.Event()
    run_event.set()

    myT = threading.Thread(target=myThread, args=(run_event,))
    myT.start()

    GObject.threads_init()
    mainloop = GObject.MainLoop()
    mainloop.run()

except (KeyboardInterrupt, SystemExit):
    mainloop.quit()
    run_event.clear()
    myT.join()
    print("Host: KeyboardInterrupt")

输出:

Thread: Print every 1 sec
Thread: Print every 1 sec
^CThread: Exit
Host: KeyboardInterrupt

(process:2429): GLib-CRITICAL **: Source ID 1 was not found when attempting to remove it

另请参阅: 使用键盘中断关闭所有线程

于 2015-02-12T11:45:23.957 回答