我偶尔希望将龙卷风协程中的逻辑暴露给交互式用户。这些用户经常按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
的某些组合在过去对我有用。
答案 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
的代码进行更改。