如何在已有运行的asyncio循环中从同步函数调用异步函数并获取结果
问题分析与解决方案
你的代码无法正常运行的核心原因是死锁:同步函数i()在事件循环所在的线程中执行,调用x.result()会直接阻塞当前线程,而异步函数hel()需要事件循环运行才能执行,最终导致事件循环被卡死,hel()永远无法完成,x.result()会一直等待下去。
在不将i()改为异步函数的前提下,可行的解决方法是把i()放到单独的线程中执行,避免阻塞事件循环线程。具体实现如下:
import asyncio from concurrent.futures import ThreadPoolExecutor async def hel(): return 4 def i(): loop = asyncio.get_running_loop() # 提交协程到事件循环,此时i()在独立线程,用run_coroutine_threadsafe是安全的 future = asyncio.run_coroutine_threadsafe(hel(), loop) result = future.result() print(result) return result async def h(): loop = asyncio.get_running_loop() # 使用线程池执行同步函数i() # 传None可直接使用asyncio默认线程池 with ThreadPoolExecutor() as executor: i_result = await loop.run_in_executor(executor, i) print(f"从i()拿到的结果: {i_result}") asyncio.run(h())
关键改动说明
- 将
i()放到线程池中执行,让它在独立于事件循环的线程里运行,这样future.result()的阻塞不会影响事件循环处理hel()协程。 asyncio.run_coroutine_threadsafe本身就是为非事件循环线程设计的,用来向事件循环提交协程,放到线程池后就能正常发挥作用。
内容的提问来源于stack exchange,提问作者the_tech_guy
相关产品推荐
相关产品推荐

