Tornado multiple IOLoop in multithreads

折月煮酒 提交于 2019-12-11 03:42:26

问题


I am trying to run multiple IOLoop in multiple threads and I am wondering how the IOLoop actually works.

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()

According to the doc, I can not use IOLoop.instance() since it's a singleton and I am working in a thread. So I created my own IOLoop. But this piece of code listens on the port 8888 but can not render any web page. I am wondering is there anything missed, or do I need to tie the http_server to the IOLoop in some way?

Also, I find that removing the last 3 lines and substitute with tornado.ioloop.IOLoop.instance().start works perfectly for single thread. But what's the difference between the singleton and self created IOLoop?

I am new to Tornado and any answers are welcomed.


回答1:


In general you should use IOLoop.current as the default when constructing an asynchronous object, and use IOLoop.instance when you mean to communicate to the main thread from a different one.

IOLoop.current without params returns already created ioloop of thread or it calls IOLoop.instance(). And HTTPServer (actually in TCPServer) use IOLoop.current to interact with ioloop, so the only thing you should change is to create ioloop before HTTPServer e.g.

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()

Also I've removed IOLoop.make_current, since it's redundant - IOLoop() sets self as a current.


Code above will work, but only with one thread, because reuse_port is not enabled by default. You will end up with:

OSError: [Errno 98] Address already in use

You can enable this with

    http_server_api.bind(port=8888, reuse_port=True)
    http_server_api.start()

instead of http_server_api.listen(8888)



来源:https://stackoverflow.com/questions/38644963/tornado-multiple-ioloop-in-multithreads

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!