She*_*ang 3 python multithreading tornado
我正在尝试在多个线程中运行多个 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()
Run Code Online (Sandbox Code Playgroud)
根据文档,我不能使用 IOLoop.instance() 因为它是一个单例并且我在一个线程中工作。所以我创建了自己的 IOLoop。但是这段代码监听了8888端口却无法渲染任何网页。我想知道是否遗漏了什么,或者我是否需要以某种方式将 http_server 绑定到 IOLoop?
此外,我发现删除最后 3 行并替换tornado.ioloop.IOLoop.instance().start为单线程完美。但是单例和自创IOLoop有什么区别呢?
我是 Tornado 的新手,欢迎提供任何答案。
通常,在构造异步对象时,您应该使用 IOLoop.current 作为默认值,而当您打算从不同的主线程与主线程进行通信时,应使用 IOLoop.instance。
IOLoop.current没有 params 返回已经创建的线程 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()
Run Code Online (Sandbox Code Playgroud)
我也删除了IOLoop.make_current,因为它是多余的 -IOLoop()将 self 设置为当前。
上面的代码可以工作,但只能使用一个线程,因为默认情况下不启用重用端口。你最终会得到:
OSError: [Errno 98] Address already in use
Run Code Online (Sandbox Code Playgroud)
你可以用
http_server_api.bind(port=8888, reuse_port=True)
http_server_api.start()
Run Code Online (Sandbox Code Playgroud)
代替 http_server_api.listen(8888)