讲师中心 微信公众号
AI工具推荐 视频效率加速

C++如何实现带优先级的任务调度器_C++使用priority_queue实例【架构】

夜静姑娘_4974

夜静姑娘_4974

发布时间:2026-02-13 08:21:39

|

563人浏览过

|

来源于php中文网

原创

priority_queue默认按大根堆排序,高优先级值反而后执行;需自定义比较器:紧急程度与数值成反比时用std::greater或a.priority>b.priority,成正比时重载operator

c++如何实现带优先级的任务调度器_c++使用priority_queue实例【架构】

priority_queue 默认比较器不支持自定义优先级逻辑

直接用 std::priority_queue 存任务对象时,它默认按 operator 降序排列(即最大堆),但多数调度场景需要「数值越小优先级越高」(如优先级数字 1 > 2 > 3),这时默认行为是反的。<br>常见错误是没重载比较逻辑,结果高数字任务反而先执行。

正确做法是提供自定义比较器,让 priority_queue 按需升序或降序:
• 若用 int priority 字段,且值越小越紧急,应使用 std::greater 或 lambda 返回 a.priority > b.priority
• 若用结构体,必须定义 operator 或传入仿函数

struct Task {
    int priority;
    std::function<void()> fn;
    bool operator<(const Task& rhs) const {
        return priority > rhs.priority; // 注意:这里反向比较,实现最小堆
    }
};
std::priority_queue<Task> queue; // 此时 priority 小的在队首

任务对象必须可移动或支持深拷贝

往 priority_queue 里 push std::function 或带指针/资源的对象时,若类型不可拷贝也不可移动(比如含 std::unique_ptr 未显式 move),编译会报错:use of deleted function。

实操建议:
• 所有任务类成员尽量用值语义(如 std::string、int)
• 若必须持有独占资源,确保类已定义移动构造函数和移动赋值运算符
• push 时显式用 std::move(task) 避免冗余拷贝
• 不要存裸指针——生命周期无法保证,调度时可能访问已释放内存

立即学习“C++免费学习笔记(深入)”;

多线程环境下 priority_queue 不是线程安全的

std::priority_queue 本身无内部锁,多个线程同时 push 或 top/pop 必然导致数据竞争,表现可能是崩溃、乱序、甚至静默逻辑错误。

C++14
C++14

C++14 对 C++11 的修正与增强版本,适合旧系统维护和较老工具链兼容。

下载

常见误用:
• 用全局 priority_queue + 多个工作线程直接操作
• 只对 pop 加锁,但没锁住 top 和 pop 的原子性(竞态窗口)

安全做法:
• 用 std::mutex 包裹整个 push/top/pop 序列
• 更高效的选择是改用无锁队列(如 moodycamel::ConcurrentPriorityQueue),但需引入第三方
• 或者采用「单生产者-单消费者」模型,用条件变量 + 队列分离调度与执行

调度器需要处理任务延迟与时间轮盘扩展性问题

纯 priority_queue 只适合立即执行或按静态优先级排序的任务。一旦加入「5 秒后执行」「每 10 秒重复」这类时间维度需求,它就力不从心了——因为每次插入都要 O(log n),且无法高效剔除过期任务。

这时候别硬改 priority_queue,考虑分层:
• 近期任务(如 1 秒内)走 priority_queue(低延迟)
• 中远期任务走基于时间轮(timing wheel)的结构,例如用 std::vector<:list>></:list> 分桶
• 所有任务统一用绝对时间戳做主排序键,避免浮点误差累积

真正容易被忽略的是:优先级和延迟不是正交的。一个「高优先级但 10 秒后才执行」的任务,不该抢占「低优先级但现在就能跑」的任务——这需要复合排序键,比如 std::tuple<time_point priority seq_id></time_point>。

热门AI工具

更多
DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

咔片AIPPT

一款在线AI演示文稿制作工具,可根据主题和内容需求辅助生成PPT结构与页面,提高演示材料制作效率。

火山引擎

火山引擎是一款面向企业的云计算与AI服务平台。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

墨刀AI
墨刀AI Hot

一款AI图像与设计工具,主要用于产品经理的专属智能体,适合需要提升相关任务效率的用户。

PixTV
PixTV Hot

PixTV是一款面向AIGC内容创作的AI视频生成工具。

Atoms
Atoms Hot

Atoms是一款AI智能体工具,第一支自动构建真实业务的 AI 团队。

PixPix
PixPix Hot

PixPix是一款面向电商视觉生产的AI商品图生成工具。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

相关专题

更多
golang结构体相关大全
golang结构体相关大全

本专题整合了golang结构体相关大全,想了解更多内容,请阅读专题下面的文章。

5094

2025.06.09

golang结构体方法
golang结构体方法

本专题整合了golang结构体相关内容,请阅读专题下面的文章了解更多。

5271

2025.07.04

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

6979

2023.08.02

int占多少字节
int占多少字节

int占4个字节,意味着一个int变量可以存储范围在-2,147,483,648到2,147,483,647之间的整数值,在某些情况下也可能是2个字节或8个字节,int是一种常用的数据类型,用于表示整数,需要根据具体情况选择合适的数据类型,以确保程序的正确性和性能。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

3345

2024.08.29

c++怎么把double转成int
c++怎么把double转成int

本专题整合了 c++ double相关教程,阅读专题下面的文章了解更多详细内容。

4368

2025.08.29

C++中int的含义
C++中int的含义

本专题整合了C++中int相关内容,阅读专题下面的文章了解更多详细内容。

2965

2025.08.29

lambda表达式
lambda表达式

Lambda表达式是一种匿名函数的简洁表示方式,它可以在需要函数作为参数的地方使用,并提供了一种更简洁、更灵活的编码方式,其语法为“lambda 参数列表: 表达式”,参数列表是函数的参数,可以包含一个或多个参数,用逗号分隔,表达式是函数的执行体,用于定义函数的具体操作。本专题为大家提供lambda表达式相关的文章、下载、课程内容,供大家免费下载体验。

1091

2023.09.15

python lambda函数
python lambda函数

本专题整合了python lambda函数用法详解,阅读专题下面的文章了解更多详细内容。

345

2025.11.08

Uvicorn 报错与问题解决教程
Uvicorn 报错与问题解决教程

本专题汇总了Uvicorn服务器常见问题与报错解决的教程合集,涵盖启动失败、端口占用、模块导入错误、事件循环冲突及热重载失效等典型故障的排查思路。同时整理了多进程与Worker配置、SSL/HTTPS证书报错、跨域与代理配置等实战解决方案,助你快速定位并解决Uvicorn运行中的各类问题。

0

2026.11.02

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C++ Core Guidelines
C++ Core Guidelines

共0课时 | 0人学习

C++ Reference
C++ Reference

共0课时 | 0人学习

C++ 官方标准说明
C++ 官方标准说明

共0课时 | 0人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn