Python 线程内的 DBusGMainLoop 和 try and catch 块
Python DBusGMainLoop inside thread and try and catch block
我目前正在尝试创建一个 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")" 没有被执行。此外,我不确定如何解决所述警告。
希望能帮到你!
其实我自己就能解决问题。
您只需将 MainLoop() 放在主线程中,然后在新线程 (myT) 中启动当前正在执行的其他操作 "print("主机:每 1 秒打印一次")"。所以你必须从上面的代码中更改线程。
然后,如果发生 KeyboardInterrupt,则必须手动退出第二个线程 (myT)。
只调用 "print("Thread: KeyboardInterrupt")" 的原因是,如果您使用 MainLoop,调用它的进程将被视为 "new main tread"。
但是,我仍然不确定如何消除错误:
(process:2429): GLib-CRITICAL **: Source ID 1 was not found when attempting to remove it
根据 post“GLib-CRITICAL **: Source ID XXX was not found when attempting to remove it”警告不是问题,所以我将忽略它。
希望这对任何偶然发现此问题的人有所帮助 post!
示例:
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
另请参阅:
Closing all threads with a keyboard interrupt
我目前正在尝试创建一个 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")" 没有被执行。此外,我不确定如何解决所述警告。
希望能帮到你!
其实我自己就能解决问题。
您只需将 MainLoop() 放在主线程中,然后在新线程 (myT) 中启动当前正在执行的其他操作 "print("主机:每 1 秒打印一次")"。所以你必须从上面的代码中更改线程。 然后,如果发生 KeyboardInterrupt,则必须手动退出第二个线程 (myT)。
只调用 "print("Thread: KeyboardInterrupt")" 的原因是,如果您使用 MainLoop,调用它的进程将被视为 "new main tread"。
但是,我仍然不确定如何消除错误:
(process:2429): GLib-CRITICAL **: Source ID 1 was not found when attempting to remove it
根据 post“GLib-CRITICAL **: Source ID XXX was not found when attempting to remove it”警告不是问题,所以我将忽略它。 希望这对任何偶然发现此问题的人有所帮助 post!
示例:
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
另请参阅: Closing all threads with a keyboard interrupt