我有以下代码无法按我预期的方式工作。我希望能够使用 SIGINT (Ctrl-C) 中断我的程序。然后它应该取消运行子进程的任务并在取消时运行一些代码,但我无法运行该部分。似乎信号被我设置的事件处理程序以外的其他东西拦截了。这不是我所期望的。
在 python 3.10.6 和 3.11.2
上运行import asyncio
import signal
jobs = set()
async def create_worker():
task = asyncio.create_task(worker())
jobs.add(task)
task.add_done_callback(jobs.discard)
async def worker():
try:
proc = await asyncio.create_subprocess_shell(
'sleep 10',
)
await proc.communicate()
print("done")
except asyncio.CancelledError:
print("my task is getting cancelled :\\") # should run this section, but doesn't
raise
async def main() -> None:
loop = asyncio.get_event_loop()
loop_hold = asyncio.Event()
async def graceful_shutdown():
if jobs:
await asyncio.sleep(2.0) # doesn't run, the jobs were stopped earlier
unfinished_jobs = list(jobs)
if unfinished_jobs:
for job in unfinished_jobs:
job.cancel()
await asyncio.wait(unfinished_jobs)
loop_hold.set()
loop.add_signal_handler(
signal.SIGINT,
lambda: asyncio.create_task(graceful_shutdown())
)
for _ in range(10):
await create_worker()
await loop_hold.wait()
if __name__ == "__main__":
asyncio.run(main())
当我在命令完成之前使用 Ctrl-C 中断程序时,我期望在取消工人时运行一些代码。也许像下面这样:
my task is getting cancelled :\
my task is getting cancelled :\
...
my task is getting cancelled :\
但我得到的是这个:
done
done
...
done
我也用
asyncio.create_subprocess_exec
试过这个,但我遇到了同样的问题。