我试图在多个线程中运行多个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绑定到IOLoop?
另外,我发现删除最后3行并用tornado.ioloop.IOLoop.instance().start
代替完全适用于单线程。但单身人士和自我创造的IOLoop有什么区别?
我是Tornado的新手,欢迎任何答案。
答案 0 :(得分:4)
没有参数的一般来说,在构造异步对象时应该使用IOLoop.current作为默认值,并且当你想要从另一个主线程与主线程进行通信时使用IOLoop.instance。
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()
将自设置为当前。
上面的代码可以使用,但只能使用一个线程,因为默认情况下不启用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)