KeyboardInterrupt期间引发线程错误



我有一个非常基本的函数,它接受一个名为name的字符串和一个回调函数。我的目标是能够通过优雅地引发键盘中断来终止函数。

在主线程上,我在观察键盘中断,而foo在后台线程上运行。

然而,在thread.join()上,我遇到了一个线程错误。

import threading
import asyncio
import sys
import time
def callback_handler(name):
print(f"Hi im a callback_handler, my name is {name}")
async def foo(name, cb):
await asyncio.sleep(5)
print("Inside foo")
if cb:
await asyncio.sleep(5)
cb(name)

event_loop = asyncio.new_event_loop()
task = event_loop.create_task(foo("bar", callback_handler))
thread = threading.Thread(target=event_loop.run_forever, daemon=True)
thread.start()

try:
while True:
message = input("> ")
except (KeyboardInterrupt, EOFError):
print('Received KeyboardInterrupt')
thread.join()

错误:

python3 cb.py
> ^CReceived KeyboardInterrupt
^CTraceback (most recent call last):
File "/Users/lamathe/Desktop/cb.py", line 34, in <module>
thread.join()
File "/usr/local/Cellar/python@3.9/3.9.13_1/Frameworks/Python.framework/Versions/3.9/lib/python3.9/threading.py", line 1060, in join
self._wait_for_tstate_lock()
File "/usr/local/Cellar/python@3.9/3.9.13_1/Frameworks/Python.framework/Versions/3.9/lib/python3.9/threading.py", line 1080, in _wait_for_tstate_lock
if lock.acquire(block, timeout):
KeyboardInterrupt

非常感谢在这方面的任何支持。

在其他问题中,如linux-不能用Ctrl-C杀死Python脚本-堆栈溢出,您可以看到Ctrl+C只停止主线程中的代码,而不停止线程中的event_loop

至于我,如果您有daemon=True,就不应该使用thread.join(),它会在代码结束时自动杀死线程。

try:
while True:
message = input("> ")
except (KeyboardInterrupt, EOFError):
print('Received KeyboardInterrupt')
# --- end of code ---

或者,您必须停止循环event_loop.stop(),然后才能等待线程结束。但它可能需要几秒钟的时间来停止循环中的一些函数。

try:
while True:
message = input("> ")
except (KeyboardInterrupt, EOFError):
print('Received KeyboardInterrupt')
print('stop loop')
event_loop.stop()

print('wait for join')
thread.join()
# --- end of code ---

最新更新