Skip to main content
 首页 » 编程设计

python之在多线程中使用 Tornado 时出现python3.6错误

2024年08月15日30yyy_WW

我只是简单地将 tornado 应用程序与线程一起使用,如下代码:

def MakeApp(): 
    return tornado.web.Application([(r"/websocket", EchoWebSocket), ]) 
 
def run_tornado_websocket(): 
    app = MakeApp() 
    http_server = tornado.httpserver.HTTPServer(app, ssl_options={ 
        "certfile": os.path.join(os.path.abspath("."), "server.crt"), 
        "keyfile": os.path.join(os.path.abspath("."), "server_no_passwd.key"), 
        }) 
 
    http_server.listen(options.port) 
    tornado.ioloop.IOLoop.current().start() 
 
if __name__ == '__main__': 
    threads = [] 
    t = threading.Thread(target=run_tornado_websocket, args=()) 
    threads.append(t) 
    for t in threads: 
        t.start() 

在python3.5上运行良好,但在python3.6和lasted tornado上运行失败,报错:

Exception in thread Thread-1: 
Traceback (most recent call last): 
  File "D:\python3\lib\threading.py", line 916, in _bootstrap_inner 
    self.run() 
  File "D:\python3\lib\threading.py", line 864, in run 
    self._target(*self._args, **self._kwargs) 
  File "D:\ssl\ws_server.py", line 49, in run_tornado_websocket 
    http_server.listen(options.port) 
  File "D:\python3\lib\site-packages\tornado\tcpserver.py", line 145, in listen 
    self.add_sockets(sockets) 
  File "D:\python3\lib\site-packages\tornado\tcpserver.py", line 159, in add_sockets 
    sock, self._handle_connection) 
  File "D:\python3\lib\site-packages\tornado\netutil.py", line 219, in add_accept_handler 
    io_loop = IOLoop.current() 
  File "D:\python3\lib\site-packages\tornado\ioloop.py", line 282, in current 
    loop = asyncio.get_event_loop() 
  File "D:\python3\lib\asyncio\events.py", line 694, in get_event_loop 
    return get_event_loop_policy().get_event_loop() 
  File "D:\python3\lib\asyncio\events.py", line 602, in get_event_loop 
% threading.current_thread().name) 
RuntimeError: There is no current event loop in thread 'Thread-1'. 

我认为在 python3.6 中 IOLOOP 有一些变化。但我不知道如何解决这个问题,真的很想知道原因。

请您参考如下方法:

从 Tornado 5.0 开始,默认使用 asyncio 事件循环。 asyncio 有一些额外的限制,因为在主线程以外的线程上启动事件循环是一种不常见的模式,而且通常是错误的。您必须通过 asyncio.set_event_loop(asyncio.new_event_loop()) 告诉 asyncio 您想要在新线程中使用事件循环,或者使用 asyncio.set_event_loop_policy(tornado.platform.asyncio. AnyThreadEventLoopPolicy()) 以禁用此限制。