使用asyncio.to_thread运行CPU密集异步函数报错求助
问题分析与解决
问题根源
asyncio.to_thread是用来把同步函数放到线程池执行的工具,但Shazam.recognize_song本身就是异步协程方法。直接把异步方法传给to_thread,只会得到一个未被执行的协程对象,不会自动触发await,所以才会出现"coroutine was never awaited"的警告,打印出的ret也只是协程对象而非实际结果。
解决方案
既然recognize_song本身是异步方法,不需要用to_thread包装,直接await即可。asyncio.gather会自动并发调度这些协程任务。修改后的代码如下:
import asyncio from shazamio import Shazam async def run_task(shazam): ret = await shazam.recognize_song('01 - Forest Drive West - Impulse.mp3') print(ret) return 1 async def run_all_tasks(iters): shazam = Shazam() coros = [run_task(shazam) for i in range(iters)] await asyncio.gather(*coros) if __name__ == '__main__': asyncio.run(run_all_tasks(10))
额外说明
只有当调用的是同步CPU密集型函数时,才需要用asyncio.to_thread将其移到线程池,避免阻塞事件循环。对于本身就支持异步的方法,直接通过await调用即可,asyncio会自动处理并发调度。
内容的提问来源于stack exchange,提问作者Sarah
相关产品推荐
相关产品推荐

