您的位置:

最佳方案处理tornado RuntimeError("Already waiting")

  发布时间:2023-02-17 09:22:02
报错的原因错误在 Python 中 Tornado 框架中可能是由于在一个 IOLoop 实例上调用了 start() 方法多次导致的。这意味着 Tornado 的 IOLoop 已经开始运行并且在等待事件,但又被试图重新启动。如何解决可以使用 IOLoop.current() 方法来避免重复启动 IOLoop。该方法返回当前线程中运行的 IOLoop 实例,如果不存在则返回 None。这样做可以确保在同一线程中 IOLoop 只会被启动一次。

报错的原因

"RuntimeError("Already waiting")" 错误在 Python 中 Tornado 框架中可能是由于在一个 IOLoop 实例上调用了 start() 方法多次导致的。这意味着 Tornado 的 IOLoop 已经开始运行并且在等待事件,但又被试图重新启动。在这种情况下,应该避免重复启动 IOLoop。

如何解决

可以使用 IOLoop.current() 方法来避免重复启动 IOLoop。该方法返回当前线程中运行的 IOLoop 实例,如果不存在则返回 None。

在你的代码中,你可以检查 IOLoop.current() 的返回值,如果为 None 则调用 IOLoop.start() 启动 IOLoop,否则不需要重新启动。


import tornado.ioloop

loop = tornado.ioloop.IOLoop.current()
if loop is None:
    loop = tornado.ioloop.IOLoop.instance()
    loop.start()

这样的话,在一个线程中如果没有IOLoop实例运行,它将会创建一个IOLoop实例并启动,如果已经有实例在运行,它将不会重复启动。

使用例子

是的,下面是一个简单的例子,展示了如何在 Tornado 中避免重复启动 IOLoop。


import tornado.ioloop
import tornado.web

class MainHandler(tornado.web.RequestHandler):
    def get(self):
        self.write("Hello, world")

def make_app():
    return tornado.web.Application([
        (r"/", MainHandler),
    ])

if __name__ == "__main__":
    app = make_app()
    app.listen(8888)
    loop = tornado.ioloop.IOLoop.current()
    if loop.asyncio_loop is None:
        loop.start()

在上面的代码中,我们首先创建了一个 Tornado Web 应用程序,然后监听了 8888 端口。之后我们使用 IOLoop.current() 获取当前线程中运行的 IOLoop 实例,如果为 None 则启动 IOLoop,否则不需要重新启动。

这样做可以确保在同一线程中 IOLoop 只会被启动一次。