You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 14:45:34