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