如何在asyncio中实现异步任务的暂停与恢复功能?
实现方案说明
关于你提到的两个工具的疑问解答
- asyncio.Lock:锁不存在所谓的“作用对象”,也不需要绑定特定的“被锁定内容”,它本质是一个互斥访问标记,所有尝试获取同一个Lock实例的代码逻辑,同一时间只会有一个能成功拿到锁继续执行,其余逻辑会自动进入等待状态。
- asyncio.Event:你可以通过调整Event的初始状态实现你要的效果:默认将Event设置为已触发状态代表允许后台循环运行,需要暂停时清除Event标记,
wait()方法就会在Event未被触发时进入等待,直到Event重新被设置,刚好匹配你的需求。
方案1:使用asyncio.Lock(适合简单互斥场景)
如果你的核心需求只是保证「后台遍历处理订单」和「提交新订单」两个逻辑不会同时执行,这个方案最简洁:
import asyncio # 全局唯一的锁实例 order_op_lock = asyncio.Lock() async def loop_orders(): while True: async with order_op_lock: do_this() do_that() # 主动让出协程调度权,避免长时间占用锁导致提交逻辑抢不到资源 await asyncio.sleep(0) async def create_order(): # 拿到锁时后台循环已经停止处理,直接执行提交逻辑 async with order_op_lock: # 你的订单提交逻辑 send_order()
方案2:使用asyncio.Event(适合灵活启停控制)
如果你需要支持多触发源暂停循环、或者需要明确等待当前批次处理完全结束后再提交订单,可以用这个方案:
import asyncio # 初始设置为已触发状态,代表允许后台循环运行 loop_allowed = asyncio.Event() loop_allowed.set() async def loop_orders(): while True: # 事件未触发时会在这里阻塞等待,直到重新被设置为允许运行 await loop_allowed.wait() do_this() do_that() await asyncio.sleep(0) async def create_order(): # 发送暂停信号 loop_allowed.clear() # 可选:等待当前正在执行的处理逻辑运行结束 await asyncio.sleep(0) try: send_order() finally: # 无论提交成功失败都要恢复循环,避免永久卡死 loop_allowed.set()
方案选择建议
- 需求仅为两个逻辑互斥执行,选Lock即可,代码更简洁,也不需要手动维护运行状态
- 需要更复杂的启停控制、多节点暂停触发,选Event可控性更强
内容的提问来源于stack exchange,提问作者Joël Brigate
相关产品推荐
相关产品推荐

