我试图在多个线程中运行多个IOLoop,但我想知道IOLoop实际如何工作。

class WebThread(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self, name='WebThread')

    def run(self):
        curdir = os.path.dirname(os.path.realpath(__file__))

        application = Application() #Very simple tornado.web.Application
        http_server_api = tornado.httpserver.HTTPServer(application)
        http_server_api.listen(8888)

        logging.info('Starting application')

        #tornado.ioloop.IOLoop.instance() is singleton, not for thread, right?

        ioloop = tornado.ioloop.IOLoop()
        ioloop.make_current()
        ioloop.start()

根据文档,我不能使用IOLoop.instance(),因为它是单例并且我正在线程中工作。因此,我创建了自己的IOLoop。但是这段代码在端口8888上监听,但无法呈现任何网页。我想知道是否有任何遗漏,还是需要以某种方式将http_server绑定(bind)到IOLoop?

另外,我发现删除最后三行并用tornado.ioloop.IOLoop.instance().start替换对于单线程非常适用。但是,单例和自行创建的IOLoop有什么区别?

我是 Tornado 的新手,欢迎回答。

最佳答案



不带参数的 IOLoop.current 返回已创建的线程ioloop的或调用IOLoop.instance()。并且HTTPServer(实际上是在TCPServer中)使用IOLoop.current与ioloop进行交互,因此您唯一需要更改的是在HTTPServer之前创建ioloop,例如

class WebThread(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self, name='WebThread')

    def run(self):
        curdir = os.path.dirname(os.path.realpath(__file__))

        ioloop = tornado.ioloop.IOLoop()

        application = Application() #Very simple tornado.web.Application
        http_server_api = tornado.httpserver.HTTPServer(application)
        http_server_api.listen(8888)

        logging.info('Starting application')

        ioloop.start()

我也删除了IOLoop.make_current,因为它是多余的-IOLoop()将self设置为当前值。

上面的代码将起作用,但仅在一个线程中起作用,因为默认情况下未启用reuse_port。您最终将得到:
OSError: [Errno 98] Address already in use

您可以使用
    http_server_api.bind(port=8888, reuse_port=True)
    http_server_api.start()

代替http_server_api.listen(8888)

关于python - 在多线程中 Tornado 多个IOLoop,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/38644963/

10-12 20:40