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

关于简单asyncio示例的理解误区与非阻塞代码修复请求

asyncio协程阻塞问题分析与修复

我有一个耗时8秒的IO任务放在协程task()中,想要实现无限循环,每5秒执行该任务且不阻塞主循环,但当前代码运行时主循环会被阻塞,输出不符合预期。

原代码

import asyncio


async def task():
    print('starting task')
    await asyncio.sleep(8)
    print('finished task')

async def main():
    count = 0
    while True:
        print(count)
        if count % 5 == 0:
            print('running task')
            await task()
        count += 1
        await asyncio.sleep(1)

asyncio.run(main())

当前输出

0
running task
starting task
finished task
1
2
3
4
5
running task
starting task
finished task
6
7
8
9
10

错误原因

你误解了await的作用:当在main里await task()时,main协程会暂停执行,直到task协程完全运行结束。哪怕task里有await asyncio.sleep(8),这只是让task暂时让出控制权给事件循环,但main因为在等待task的结果,所以不会继续往下执行,直到task的sleep完成、整个task结束后,main才会继续计数和睡眠。

修复方案

要让task在后台运行不阻塞main,需要用asyncio.create_task()将协程包装成一个后台任务,这样事件循环会调度它运行,而main不需要等待它完成,可以继续执行自己的逻辑。

修改后的代码

import asyncio


async def task():
    print('starting task')
    await asyncio.sleep(8)
    print('finished task')

async def main():
    count = 0
    while True:
        print(count)
        if count % 5 == 0:
            print('running task')
            # 用create_task创建后台任务,不阻塞main
            asyncio.create_task(task())
        count += 1
        await asyncio.sleep(1)

asyncio.run(main())

修复后输出示例

0
running task
starting task
1
2
3
4
5
running task
starting task
6
7
8
finished task
9
10
starting task
...

可以看到,主循环的计数不会被阻塞,task在后台运行,8秒后输出finished task,同时主循环继续正常执行。

内容的提问来源于stack exchange,提问作者AndrewK

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 17:17:19