使用while循环与lock.locked()检查时程序卡在await语句的原因排查
asyncio锁配合while循环导致任务卡住的原因
你的代码卡住的核心问题出在while循环内无await的同步轮询,以及错误的锁使用逻辑:
无await的循环抢占事件循环
当第一个任务获取锁并进入await asyncio.sleep(...)时,事件循环会切换到其他work任务。但这些任务进入while True循环后,lock_browser.locked()是同步判断,没有任何await语句让出控制权,会一直占用事件循环线程,导致第一个任务的sleep结束后无法被调度执行,锁也就永远无法释放。手动判断锁状态的冗余与风险
asyncio.Lock的async with上下文管理器本身就会自动等待锁释放,不需要手动循环判断锁状态。你的手动判断不仅多余,还会引发竞争条件——多个任务可能同时检测到锁未被占用,随后争抢锁,最终只有一个任务能成功,其余任务会陷入无意义的循环阻塞。
修正后的代码
import asyncio import random import time async def work(lock_browser, x, y): async with lock_browser: await asyncio.sleep(random.uniform(3, 5)) # 模拟单浏览器访问网站的耗时 print(x, y) async def main(x): tasks = [] lock_browser = asyncio.Lock() for y in range(5): tasks.append(work(lock_browser, x, y)) await asyncio.gather(*tasks) if __name__ == "__main__": start = time.perf_counter() for x in range(5): asyncio.run(main(x)) end = time.perf_counter() duration = end - start print(f'Time elapsed:{duration:.2f}s')
直接使用async with lock_browser即可自动处理锁的等待、获取与释放,同时在等待锁时会让出事件循环控制权,不会阻塞其他任务调度。
内容的提问来源于stack exchange,提问作者jguy
相关产品推荐
相关产品推荐

