RuntimeError:线程'Thread-1'中没有当前事件循环,多线程和asyncio错误

时间:2018-02-10 21:45:21

标签: python multithreading python-asyncio

我有一个调用asyncio循环的线程,但这会导致提到的异常:

RuntimeError: There is no current event loop in thread 'Thread-1'.

这个问题:RuntimeError: There is no current event loop in thread in async + apscheduler遇到了同样的问题,但他们提到的是我没有的调度程序。

我的代码如下:

def worker(ws):
      l1 = asyncio.get_event_loop()
      l1.run_until_complete(ws.start())  


      l2 = asyncio.get_event_loop()
      l2.run_forever()


if __name__ == '__main__':
    ws = Server()
    p = threading.Thread(target=worker,args=(ws,))
    p.start()


    while True:
        try:
            #...do sth
        except KeyboardInterrupt:
            p.join()
            exit() 

3 个答案:

答案 0 :(得分:7)

新主题没有事件循环,所以你必须明确地传递和设置它:

def worker(ws, loop):
    asyncio.set_event_loop(loop)
    loop.run_until_complete(ws.start())

if __name__ == '__main__':
    ws = Server()
    loop = asyncio.new_event_loop()
    p = threading.Thread(target=worker, args=(ws, loop,))
    p.start()

此外,p.join()不会正确终止您的脚本,因为您永远不会停止服务器,因此您的循环将继续运行,可能会挂起该线程。在加入线程之前,你应该像loop.call_soon_threadsafe(ws.shutdown)一样调用smth,理想情况下等待服务器的正常关闭。

答案 1 :(得分:0)

在具有Python 3.7.3的Windows上,而不是直接在线程中创建事件循环,

我必须:

asyncio.set_event_loop_policy(asyncio.WindowsProactorEventLoopPolicy())
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)

否则,问题将继续存在。

答案 2 :(得分:0)

我在线程中运行Bokeh Server时遇到此问题。当我尝试创建服务器= Server({'/':app},port = 0)时,会出现此错误。从龙卷风文档中,我发现了以下内容……

Class tornado.platform.asyncio.AnyThreadEventLoopPolicy[source]

事件循环策略,允许在任何线程上创建循环。 默认的asyncio事件循环策略仅在主线程中自动创建事件循环。其他线程必须显式创建事件循环,否则asyncio.get_event_loop(因此IOLoop.current)将失败。安装此策略后,可以在任何线程上自动创建事件循环,以匹配5.0之前的Tornado版本(或Python 2上为5.0)的行为。

用法:

asyncio.set_event_loop_policy(AnyThreadEventLoopPolicy())

http://www.tornadoweb.org/en/stable/asyncio.html#tornado.platform.asyncio.AnyThreadEventLoopPolicy