首页 > 解决方案 > 在 Thread 中使用 asyncio 的问题

问题描述

如下使用 asyncio 没有问题。

import asyncio


async def main():
    await asyncio.sleep(1)
    aaa = 1
    print (aaa)


loop = asyncio.get_event_loop()
loop.run_until_complete(main())
loop.close()

但是,我必须在 Thread 中使用 asyncio,如下面的简单代码所示,这会导致错误如下

import asyncio
import threading

async def main():
    await asyncio.sleep(1)
    aaa = 1
    print (aaa)


def test():
    loop = asyncio.get_event_loop()
    loop.run_until_complete(main())
    loop.close()


t=threading.Thread(target=test)
t.start()

错误消息(RuntimeError:线程 'Thread-1' 中没有当前事件循环。)

Exception in thread Thread-1:
Traceback (most recent call last):
  File "D:\Anaconda3\Lib\threading.py", line 932, in _bootstrap_inner
    self.run()
  File "D:\Anaconda3\Lib\threading.py", line 870, in run
    self._target(*self._args, **self._kwargs)
  File "D:/Test/Test4/main.py", line 57, in test
    loop = asyncio.get_event_loop()
  File "D:\Anaconda3\Lib\asyncio\events.py", line 639, in get_event_loop
    raise RuntimeError('There is no current event loop in thread %r.'
RuntimeError: There is no current event loop in thread 'Thread-1'.

如何在 Thread 中使用 asyncio?

这对我来说非常重要。我已经为这个问题苦苦挣扎了两天。

我会很感激你的帮助。

标签: pythonmultithreadingpython-asyncio

解决方案


除非您需要使用预先存在的事件循环(这里不是这种情况)或支持 Python 3.6,否则请使用asyncio.run而不是手动处理循环:

def test():
    asyncio.run(main())

这始终确保存在有效的事件循环,并处理适当的清理。

这个函数总是创建一个新的事件循环并在最后关闭它。它应该用作 asyncio 程序的主要入口点,并且最好只调用一次。


请注意,asyncio与线程结合时,事件循环通常应在主循环中运行(参见例如bpo#34697)。与其为 生成线程asyncio,不如为程序的同步部分生成一个线程。

# launch synchronous work in child threads
t=threading.Thread(target=my_sync_tasks)
t.start()

# launch asynchronous work in main thread
asyncio.run(main())
t.join()

推荐阅读