在Windows上使用Python 3.4.1,我发现在执行一个asyncio事件循环时 ,我的程序不能被中断(即在terminal中按Ctrl + C)。 更重要的是,SIGINT信号被忽略。 相反,我已经确定,不在事件循环中处理SIGINT。
为什么SIGINT在执行asyncio事件循环时被忽略?
下面的程序应该演示这个问题 – 在terminal中运行它,并尝试通过按Ctrl + C来停止它,它应该继续运行:
import asyncio import signal # Never gets called after entering event loop def handler(*args): print('Signaled') signal.signal(signal.SIGINT, handler) print('Event loop starting') loop = asyncio.SelectorEventLoop() asyncio.set_event_loop(loop) loop.run_forever() print('Event loop ended')
参见关于官方(郁金香)邮件列表的讨论 。
我找到了一个解决方法,即安排周期性的回调。 在运行时,SIGINT显然是处理的:
import asyncio def wakeup(): # Call again loop.call_later(0.1, wakeup) print('Event loop starting') loop = asyncio.SelectorEventLoop() # Register periodic callback loop.call_later(0.1, wakeup) asyncio.set_event_loop(loop) loop.run_forever() print('Event loop ended')
不知道为什么这是必要的,但它表明信号被阻塞,而事件循环等待事件(“民意调查”)。
这个问题已经在官方(郁金香)邮件列表上讨论过了 ,我的解决方法显然是现在的方式。
一个修补程序据说已经进入了Python 3.5 ,所以希望我的解决方法将被Python版本淘汰。
我发现,当执行一个asyncio事件循环时,我的程序不能被中断(即通过在终端中按Ctrl + C)
澄清:ctrl-C可能不起作用,但ctrl-break工作得很好。
通常情况下,你可以使用loop.add_signal_handler()
添加一个回调函数,但显然不幸的是这个函数不支持内置的Windows事件循环:
定期检查可以使用,是的。 否则,回路将在signal
模块捕获信号的能力之外运行。