Python asyncio能否运行次级事件循环或实现优先await?
在Python asyncio中实现优先await的方案
你要的效果是让foo中的priority1和priority2执行完成前,不将控制权交还给主事件循环,不让bar这类低优先级任务抢占调度。这是可行的,以下是几种实现方案:
方案1:用同步sleep替代异步sleep
直接把priority1和priority2里的await asyncio.sleep换成同步的time.sleep,这样当这两个任务执行sleep时会阻塞整个线程,主事件循环无法调度其他任务,直到它们完成:
import asyncio import time async def priority1(): print("p1 before sleep") time.sleep(11) # 同步sleep,阻塞整个线程 print("p1 after sleep") async def priority2(): print("p2 before sleep") time.sleep(11) print("p2 after sleep") async def foo(): while True: print("foo before sleep") await asyncio.gather(priority1(), priority2()) print("foo after sleep") async def bar(): while True: print("bar before sleep") await asyncio.sleep(5) print("bar after sleep") async def main(): await asyncio.gather(foo(), bar()) asyncio.run(main())
执行顺序:
foo before sleep bar before sleep p1 before sleep p2 before sleep p1 after sleep p2 after sleep bar after sleep
优缺点:实现最简单,但会阻塞整个事件循环,期间所有其他任务都无法运行,仅适合不需要其他任务并行的场景。
方案2:暂停非优先级任务
通过手动暂停bar任务,等priority1和priority2完成后再恢复,避免其抢占调度:
import asyncio async def priority1(): print("p1 before sleep") await asyncio.sleep(11) print("p1 after sleep") async def priority2(): print("p2 before sleep") await asyncio.sleep(11) print("p2 after sleep") async def foo(bar_task): while True: print("foo before sleep") bar_task.pause() # 暂停bar任务 await asyncio.gather(priority1(), priority2()) bar_task.resume() # 恢复bar任务 print("foo after sleep") async def bar(): while True: print("bar before sleep") await asyncio.sleep(5) print("bar after sleep") async def main(): bar_task = asyncio.create_task(bar()) await asyncio.gather(foo(bar_task), bar_task) asyncio.run(main())
优缺点:不会阻塞整个事件循环(仅暂停指定任务),但需要手动管理任务的暂停/恢复,适合只有少量非优先级任务的场景。注意Task.pause()和Task.resume()是Python 3.7+引入的API。
方案3:在独立线程中运行次级事件循环
创建新线程运行次级事件循环,等待其完成后再继续主协程,本质是通过线程阻塞实现优先级:
import asyncio import threading def run_sub_loop(coro): loop = asyncio.new_event_loop() asyncio.set_event_loop(loop) loop.run_until_complete(coro) loop.close() async def priority1(): print("p1 before sleep") await asyncio.sleep(11) print("p1 after sleep") async def priority2(): print("p2 before sleep") await asyncio.sleep(11) print("p2 after sleep") async def foo(): while True: print("foo before sleep") # 在新线程启动次级事件循环执行优先级任务 thread = threading.Thread(target=run_sub_loop, args=(asyncio.gather(priority1(), priority2()),)) thread.start() thread.join() # 等待次级循环完成 print("foo after sleep") async def bar(): while True: print("bar before sleep") await asyncio.sleep(5) print("bar after sleep") async def main(): await asyncio.gather(foo(), bar()) asyncio.run(main())
优缺点:可以在次级循环中处理复杂异步逻辑,但线程切换有额外开销,且同样会阻塞主协程线程,适合需要隔离异步环境的场景。
内容的提问来源于stack exchange,提问作者Pearl
相关产品推荐
相关产品推荐

