You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 02:12:00