为Asyncio代码添加多线程层出现协程未await报错如何解决
问题产生原因
- 你将
async定义的协程函数AsyncJobThread直接作为线程入口传给了_thread.start_new_thread,线程仅能执行普通同步函数,无法识别、调度协程运行,因此直接抛出协程未被等待的警告。 - 你直接在子线程中调用主线程的
loop对象创建任务,asyncio的事件循环不是线程安全的,跨线程操作事件循环本身就会触发未定义行为,就算临时修复协程执行问题后也会出现其他异常。 - 修改后的
main是普通同步函数,你调用loop.run_until_complete(main())属于错误用法,该方法仅能接收协程对象作为参数。
解决方案
每个子线程需要单独创建属于自己的事件循环,在子线程内部独立调度自身的协程任务即可,推荐使用更易用的threading模块替代低级的_thread管理线程生命周期,修正后的代码如下:
import asyncio import threading async def startAsyncJob(): # 你的业务逻辑保留在此处 pass # 线程内的协程逻辑 async def async_job_logic(frequency): while True: asyncio.create_task(startAsyncJob()) await asyncio.sleep(frequency) # 线程入口:同步函数,内部初始化当前线程专属的事件循环 def AsyncJobThread(frequency): loop = asyncio.new_event_loop() asyncio.set_event_loop(loop) try: loop.run_until_complete(async_job_logic(frequency)) finally: loop.close() def main(): try: t1 = threading.Thread(target=AsyncJobThread, args=(1,)) t2 = threading.Thread(target=AsyncJobThread, args=(15,)) # 配置为守护线程,主线程退出时自动终止子线程 t1.daemon = True t2.daemon = True t1.start() t2.start() # 主线程阻塞等待子线程运行 t1.join() t2.join() except Exception as e: print(f"Error: unable to start thread, {e}") if __name__ == "__main__": main()
该实现中每个线程持有独立的事件循环,避免了跨线程操作事件循环的问题,符合asyncio的线程安全要求,线程入口为普通同步函数符合线程调用规则,不会再出现协程未被await的报错。
内容的提问来源于stack exchange,提问作者Mit94
相关产品推荐
相关产品推荐

