为什么我不能在asyncio事件循环运行时捕获SIGINT?

在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模块捕获信号的能力之外运行。