在KeyboardInterrupt之后关闭并重置Tornado IOLoop

时间:2015-10-08 20:04:55

标签: python tornado

我偶尔希望将龙卷风协程中的逻辑暴露给交互式用户。这些用户经常按Ctrl-C来中断长时间运行的计算。这使得IOLoop处于一种不愉快的状态,可以用于未来的互动。

In [1]: from tornado import gen
In [2]: from tornado.ioloop import IOLoop
In [3]: IOLoop.current().run_sync(lambda: gen.sleep(100000))
KeyboardInterrupt: 

In [4]: IOLoop.current().run_sync(lambda: gen.sleep(1))
RuntimeError: IOLoop is already running

我应该在[3][4]之间执行哪些操作来清理或替换卡住的IOLoop。 .stop.close.close_current.close_instance的某些组合在过去对我有用。

1 个答案:

答案 0 :(得分:1)

KeyboardInterrupt后,IOLoop处于未定义状态,无法安全重启。 (对于大多数对象都是如此:除非该方法是只读方法,否则在方法被中断后对象仍然很少可用。)

如果您希望能够从C-c恢复,则必须编写自己的信号处理程序,而不是使用引发KeyboardInterrupt的默认信号处理程序。例如,要简单地停止IOLoop并使其处于可重新启动状态,您可以执行以下操作(未经测试):

def sigint_handler(sig, frame):
    io_loop = IOLoop.current()
    io_loop.add_callback_from_signal(io_loop.stop())
signal.signal(signal.SIGINT, sigint_handler)

如果您想以这种方式中断后引发异常,则必须对调用IOLoop.start的代码进行更改。