为何Python事件循环创建顺序不同导致Ctrl+C终止效果有差异?
两段asyncio代码的Ctrl+C终止差异原因分析
在Python 3.11.1(Windows系统)环境下,执行第一段代码时无法通过Ctrl+C终止程序,但第二段代码可以正常终止,两段代码的差异仅在于loop2的创建时机。
第一段无法终止的代码
import asyncio loop1 = asyncio.new_event_loop() asyncio.set_event_loop(loop1) loop2 = asyncio.new_event_loop() loop1.run_forever()
第二段可正常终止的代码
import asyncio # execute this first loop2 = asyncio.new_event_loop() loop1 = asyncio.new_event_loop() asyncio.set_event_loop(loop1) loop1.run_forever()
差异原因
这是Windows系统下asyncio事件循环的信号处理机制导致的:
- 在Windows上,asyncio的默认事件循环(ProactorEventLoop)在创建时,会尝试注册
Ctrl+C(对应SIGINT信号)的处理函数,用于终止运行中的循环。 - 事件循环的信号处理注册是全局绑定的,最后一个被创建的事件循环会接管这个全局绑定。
- 第一段代码中:先创建
loop1并设为当前循环,再创建loop2——此时loop2覆盖了全局的信号处理绑定,但实际运行的是loop1,未启动的loop2无法响应Ctrl+C信号,导致loop1也无法捕获信号,程序无法终止。 - 第二段代码中:先创建
loop2(它先注册信号处理),接着创建loop1并设为当前循环——此时loop1会重新接管全局信号处理绑定,运行loop1时,Ctrl+C信号能被正常捕获,程序可以终止。
内容的提问来源于stack exchange,提问作者mehee
相关产品推荐
相关产品推荐

