在 C++26 之前,如果想给并发任务加点优先级,要么靠操作系统的 pthread 优先级,要么用第三方库自己封一层队列。这两种做法要么平台绑定,要么维护成本高,还容易出 bug。C++26 终于在标准层面把任务优先级纳入了并发模型,它基于已有的执行器(executor)框架,提供了四个明确的优先级层级,配合调度器就能让关键任务抢先执行。
四个优先级层级
标准定义了四个逻辑优先级,由高到低:
| 优先级名称 | 数值 | 典型用途 |
|---|---|---|
| critical | 3 | 实时响应、中断处理 |
| high | 2 | 用户交互、动画更新 |
| normal | 1 | 默认任务级别 |
| low | 0 | 后台计算、数据持久化 |
数值越大,在调度时越优先。没有显式指定优先级的任务,一律视为 normal。
基本用法
提交一个高优先级任务像这样:
std::priority_executor exec;
auto future = std::async(exec, std::priority::high, [] {
return process_user_input();
});
std::priority_executor 是支持优先级调度的执行器,std::priority::high 是标准枚举值。调度器内部会维护多级队列,大致流程如下:
graph TD
A[新任务提交] --> B{是否指定优先级?}
B -->|是 | C[插入对应优先级队列]
B -->|否 | D[插入 normal 队列]
C --> E[调度器轮询高优先级队列]
D --> E
E --> F[执行最高非空队列头部任务]
这是调度器的理想化模型,具体实现可能更复杂,比如工作窃取或线程池。
设计原理:统一调度抽象
C++26 的执行器模型本身就是一次抽象进步。回想一下,早期我们直接操作 std::thread,后来有了 std::async,再到协程和 std::execution 调度器,每一步都在减少直接对线程的依赖。加入优先级之后,执行器接口扩展了几个概念:get_priority() 查询当前优先级,schedule(task, priority) 提交带优先级的任务。
优先级枚举大致是这样:
namespace std {
enum class priority {
low = 0,
normal = 1,
high = 2,
critical = 3
};
}
当然最终名字可能是 std::execution::priority,这里只是示意。重要的是,这个抽象不需要关心底层是 Linux 的 nice 值还是 Windows 的优先级类,标准库会负责映射。
跨平台映射
一个常见映射关系:

