让1个任务用time.sleep(0.5)阻塞,另外3个任务只需要asyncio.sleep(0.1),验证同步阻塞调用是怎么拖慢整个事件循环上所有任务的。
同一个事件循环里,混入一个的同步阻塞调用。
代码async def blocking_worker(i): time.sleep(0.5) # 的同步阻塞调用,不是await return i async def async_worker(i): await asyncio.sleep(0.1) # 的异步等待 return i await asyncio.gather( blocking_worker(0), async_worker(1), async_worker(2), async_worker(3), )
task1、task2、task3本身只需要等0.1秒——按理说应该在0.1秒左右就完成。但它们跟task0(需要卡住0.5秒的同步调用)在同一个事件循环里跑。
统一从gather开始计时,看每个任务完成的时间点。
结果(task0用time.sleep阻塞)总耗时: 0.6063s task0 在 0.5049s 完成 task1 在 0.6062s 完成 ← 本来只要0.1s,被拖到0.6s! task2 在 0.6062s 完成 task3 在 0.6062s 完成 结果(对照组:全部用asyncio.sleep)总耗时: 0.5008s task0 在 0.5008s 完成 task1 在 0.1011s 完成 ← 还是原本的0.1s task2 在 0.1011s 完成 task3 在 0.1011s 完成
原因:time.sleep() 是一个真正的同步阻塞调用,它会占住唯一的那个线程整整0.5秒——在这0.5秒里,事件循环压根没有机会去推进task1、task2、task3的执行,哪怕它们只需要0.1秒就能跑完。等task0的同步调用结束、把控制权交还给事件循环,task1-3才有机会开始跑它们的0.1秒等待,所以它们的完成时间被推到了0.5+0.1=0.6秒左右。
每一步都是本文上面用Python 3.14跑出来的原始结果。
time.sleep(同步阻塞) vs asyncio.sleep(异步让出):对比