Python async异步编程create_task任务执行顺序不符预期问题求解
Python异步任务执行顺序异常原因解析
核心问题1:没有正确等待异步任务执行完成
asyncio.create_task()的作用只是将协程包装为任务,提交到事件循环的待调度队列,调用后不会阻塞当前代码等待任务跑完。你当前写的main函数在创建完三个任务后就直接执行结束,事件循环会进入回收流程,此时任务的调度是不完整的,输出顺序完全随机,没有参考性。
如果要保证所有任务都能被正常调度执行完,必须显式等待任务完成,参考写法:
import asyncio async def main(): print('Script start...') t1 = asyncio.create_task(task1()) t3 = asyncio.create_task(task3()) t2 = asyncio.create_task(task2()) # 等待所有任务执行完毕 await asyncio.gather(t1, t2, t3)
核心问题2:阻塞操作破坏了异步调度逻辑
你遇到task3比task2先完成的情况,本质是你的数据库插入操作没有实现真正的异步:
- 异步并发的核心逻辑是:任务遇到IO等待(网络请求、数据库交互、磁盘读写)时,会主动通过
await关键字把CPU执行权交还给事件循环,事件循环就可以趁这个等待的空档去跑其他就绪的任务。 - 如果你使用的是同步数据库驱动(比如pymysql、同步版psycopg2),整个数据库插入过程会直接卡住事件循环所在的线程,不会让出执行权,此时多个任务本质是串行阻塞执行的,完成顺序和创建顺序没有必然联系,完全受系统调度、IO返回时机影响。
- 如果你换成对应的异步驱动(比如aiomysql、asyncpg),并且在数据库操作前正确加了
await,那么耗时25-30秒的task2一定会比耗时300-400秒的task3先完成,和你的预期一致。
额外注意
不要认为给函数加了async关键字就自动获得异步能力:如果async函数内部没有任何await调用、全是同步阻塞逻辑,那它和普通同步函数的执行效果没有区别,根本不会产生并发效果。异步任务的完成顺序永远和任务本身的实际耗时、IO触发时机有关,和任务创建的先后顺序没有绑定关系。
内容的提问来源于stack exchange,提问作者Marchel Gunawan Dwi Steya
相关产品推荐
相关产品推荐

