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

时间:2014-07-16 07:42:52

标签: windows signals python-3.4 event-loop python-asyncio

在Windows上使用Python 3.4.1,我发现在执行asyncio event loop时,我的程序不能被中断(即在终端中按Ctrl + C)。更重要的是,SIGINT信号被忽略。相反,我已确定在不在事件循环中时处理SIGINT。

为什么执行asyncio事件循环时会忽略SIGINT?

以下程序应该说明问题 - 在终端中运行它并尝试通过按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')

请参阅官方(Tulip)邮件列表上的discussion

3 个答案:

答案 0 :(得分:10)

我找到了一种解决方法,即安排定期回调。在运行时,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')

不确定为什么这是必要的,但它表明在事件循环等待事件时信号被阻止("民意调查")。

此问题已在官方(郁金香)邮件列表上discussed,我的解决方法显然是截至目前的方式。

更新

一个修复程序应该是made its way into Python 3.5,所以希望我的解决方法将被Python版本淘汰。

答案 1 :(得分:6)

  

我发现在执行asyncio事件循环时,我的程序无法中断(即在终端中按Ctrl + C)

澄清一下:ctrl-C可能不起作用,但ctrl-break工作正常。

答案 2 :(得分:2)

通常情况下,您可以使用loop.add_signal_handler()为这些添加回调,但很明显,内置的Windows事件循环不支持此功能:/

可以使用定期检查,是的。否则,循环运行在signal模块捕获信号的能力之外。