我偶尔想向交互式用户公开 Tornado 协程中的逻辑。这些用户经常按 Ctrl-C
来中断长时间运行的计算。这会使 IOLoop 处于不适合 future 交互的状态。
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
的某些组合过去对我有用。
最佳答案
在发生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
的代码。
关于python - KeyboardInterrupt 后关闭并重置 Tornado IOLoop,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33024994/