我有一个非常基本的函数,它接受一个名为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 ---