我试图在多个线程中运行多个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/