asyncio本身不支持任务优先级,需自行实现带排序逻辑的异步队列;asyncio.priorityqueue在3.12+才真正可用,此前版本仅为无功能空壳。

asyncio 本身不支持任务优先级,得自己造轮子
Python 标准库的 asyncio 没有内置优先级调度机制——asyncio.create_task() 提交的任务一律按事件循环顺序“先进先出”,哪怕你用 asyncio.sleep(0) 让出控制权,也不能插队。真要实现优先级,必须绕过默认的 asyncio.Queue,自己封装一个带排序逻辑的异步队列。
用 asyncio.PriorityQueue?别信文档里的误导
标准库确实有个 asyncio.PriorityQueue,但它只在 Python 3.12+ 才真正可用;3.11 及更早版本里它只是个空壳(继承自 asyncio.Queue,但没重写 _get 方法),实际行为和普通队列完全一样。实测中往里塞 (1, coro) 和 (100, coro),取出顺序仍是插入顺序。
- Python
- Python ≥ 3.12:可用,但内部用的是
heapq,要求优先级值可比较,且put_nowait()不检查满容量,容易触发asyncio.QueueFull - 生产环境建议统一自实现,避免版本差异带来的隐性 bug
手写 PrioritizedTaskQueue:关键在 _get 和锁粒度
核心是继承 asyncio.Queue 并重写 _get(),用 heapq 维护最小堆(低数值=高优先级)。注意不能只改 get(),因为底层 _get() 才被事件循环直接调用;同时要加锁防止多消费者并发取任务时堆结构错乱。
python-docx Skill功能概述python-docx Skill是一项面向实际任务的技能,主要用于本Skill提供使用python-docx生成专业Word文档的标准方法和最佳实践;生成安全服务方案文档;核心要点生成技术架构设计文档;生成任何需要专业排版的Word文档;核心库 : python-docx;使用与执行辅助库 : docx.shared , docx.enum , docx.oxml.ns;标准代码模板;1. 文档初始化;2. 字体设置(必须!它将相关步骤、工具调用和结果整理方式集
import asyncio
import heapq
<p>class PrioritizedTaskQueue(asyncio.Queue):
def _init(self, maxsize):
self._queue = []</p><pre class="brush:python;toolbar:false;">def _put(self, item):
heapq.heappush(self._queue, item)
def _get(self):
return heapq.heappop(self._queue)使用示例:(priority, coro_func, *args)
async def worker(q): while True: priority, coro, args = await q.get() try: await coro(args) finally: q.task_done()
async def high_prio_job(x): print(f"? 高优: {x}")
async def main(): q = PrioritizedTaskQueue() asyncio.create_task(worker(q))
await q.put((1, high_prio_job, "urgent")) await q.put((10, high_prio_job, "normal")) await q.join() # 等待所有任务完成
优先级设计的坑:浮点精度、相等优先级、协程延迟开销
真实场景里优先级不是简单的整数比大小——比如两个任务都标了 priority=1,谁先执行?heapq 不保证稳定排序,可能每次结果不同;另外,把协程对象直接塞进队列会提前触发其创建开销,影响调度灵敏度。
- 解决相等优先级:用元组
(priority, timestamp, coro),timestamp用time.time_ns()避免碰撞 - 避免协程过早实例化:队列里存
(priority, callable, args, kwargs),在 worker 里才调用callable(*args, **kwargs) - 别用浮点数当优先级:
0.1 + 0.2 != 0.3在 heapq 中可能导致排序异常 - 高频率提交任务时,
heapq.heappush/pop的 O(log n) 开销可接受,但若每秒上万次入队,要考虑用分层队列(如按优先级分多个 FIFO 队列)
优先级不是银弹:它解决的是“谁先抢到 CPU 时间片”,但不解决单个协程阻塞(比如同步 IO)导致整个事件循环卡住的问题——该加 loop.run_in_executor 还得加。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










