C++ 实现异步延迟任务的优先级调度分发引擎 _ 源码【实战】

风杰同学_8721

风杰同学_8721

2026-05-20

971人浏览

原创

该文提出五种c++延迟任务调度方案:一、多级独立队列轮询,避免锁竞争;二、时间轮与优先级队列混合调度,解耦短/长延迟任务;三、c++26标准库协程调度;四、std::jthread+stop_token带状态记忆轮询;五、支持取消与退避重试的retrytask封装。

c++ 实现异步延迟任务的优先级调度分发引擎 _ 源码【实战】

一、基于多级独立队列的轮询调度实现

该方法通过为不同优先级任务分配独立队列,避免单 priority_queue 在并发环境下的锁竞争与调度僵化问题。每个队列使用独立互斥锁,轮询器按固定顺序扫描非空队列并取一个任务执行,从而保障高优先级任务不被低优先级任务阻塞,同时防止某一级别长期独占线程。

1、定义优先级枚举:使用 enum class Priority { HIGHEST = 0, HIGH = 1, MEDIUM = 2, LOW = 3, LOWEST = 4 };

2、声明多级队列容器:std::array<:queue>, 5> queues;

3、为每级队列声明独立 std::mutex:std::array<:mutex> mutexes;

4、在调度主循环中维护当前轮询索引 current_level,并在每次迭代开始前检查 token.stop_requested();

5、对 current_level 对应队列调用 try_lock(),成功则 pop 任务并立即检查 cancelled.load(),失败则跳至下一级;

6、若某级队列为空或锁获取失败,递增 current_level 并对 5 取模,继续轮询;

7、任务取出后,根据 scheduled_at 字段判断是否已到期:若未到期,则重新入队至对应优先级队列(不改变原始 priority),并继续下一轮轮询。

二、融合时间轮(Timing Wheel)与优先级队列的混合调度

该方法将延迟任务与即时任务解耦处理:短期延迟(≤ 64ms)由时间轮高效触发,长期延迟及高优先级即时任务交由多级优先队列分发。时间轮采用无锁数组结构,避免频繁内存分配,且与优先级队列共享同一 stop_token 退出机制,确保调度器整体一致性。

1、初始化 8 层时间轮(每层 256 槽),支持最大延迟约 16 秒;

2、任务入队时,若 delay ≤ 64ms,插入对应时间轮槽位;否则根据 priority 字段落入对应多级队列;

3、调度线程每 1ms 调用一次 tick(),遍历当前槽位所有任务,将其 move 到对应优先级队列头部;

4、在轮询多级队列前,先执行一次 tick(),确保刚到期任务已就绪;

5、为防止时间轮槽位堆积,每个槽位使用 std::vector 存储,并在 move 后 clear();

6、所有 Task 对象存储于 std::pmr::unsynchronized_pool_resource 分配器中,规避 new/delete 频繁调用开销;

7、时间轮指针推进与队列轮询必须在同一原子周期内完成,使用 std::atomic_thread_fence(std::memory_order_acquire) 保证可见性。

三、C++26 std::priority_task_queue + std::execution::async_policy 协同调度

该方法直接利用 C++26 标准库新特性构建轻量级异步延迟调度引擎,无需手动管理线程与锁。std::priority_task_queue 提供线程安全的优先级入队/出队,配合 std::execution::async_policy 实现任务提交即调度,延迟由任务体内部 co_await std::when_timeout() 控制,适用于对标准合规性要求严格的工业场景。

1、包含头文件:#include 和 #include ;

2、定义任务结构体,含 priority 字段与 action 成员函数对象;

3、构造 std::priority_task_queue,传入自定义比较器 cmp,确保 priority 值小者优先;

C++14
C++14

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

下载

4、封装 submit_delayed() 函数:接收 delay 参数,内部创建协程,首句为 co_await std::when_timeout(delay);

5、协程挂起后,将封装后的可调用对象以 async_policy 提交至 queue;

6、启动专用调度线程,循环调用 queue.process_one(),该函数自动处理协程恢复与异常捕获;

7、当 stop_token 触发时,process_one() 返回 false,线程安全退出,无需手动 join 或 detach。

四、基于 std::jthread + stop_token 的带状态记忆轮询器

该方法聚焦于调度器生命周期控制的健壮性,使用 std::jthread 替代裸 std::thread,结合 stop_token 实现零竞态退出。轮询逻辑携带状态记忆(如 last_served_level、consecutive_high_count),用于动态调节轮询权重,缓解高优先级任务持续涌入导致的低优先级任务饥饿问题。

1、在 ThreadPool 构造函数中初始化 std::jthread scheduler_thread,绑定成员函数 run_scheduler;

2、run_scheduler 函数开头即检查 token.stop_requested(),若为 true 则立即 return;

3、维护 std::atomic last_served_level{0} 与 std::array<:atomic>, 5> level_counters;

4、每次成功执行一个任务后,对应 level_counters[current_level].fetch_add(1);

5、若 level_counters[current_level] > 3,则强制跳过下两个同级轮询机会,转而尝试 next_level;

6、每次 pop 任务前,再次调用 token.stop_requested(),若已请求停止,则放弃本次 pop 并 break 循环;

7、任务执行体 lambda 显式接收 std::stop_token,并在 sleep 或 I/O 等待前插入 token.stop_requested() 检查。

五、支持取消与退避重试的延迟优先级任务封装

该方法面向真实业务场景,将延迟、优先级、取消、重试四大能力统一建模为 RetryTask 类型。每个任务携带 base_delay、max_retry、backoff_factor 与 priority 字段,调度引擎仅需识别其为可重试类型,即可自动注入退避逻辑与超时熔断,无需上层重复编码。

1、定义 RetryTask 继承自 Task,新增 retry_count、next_delay_ms、max_retry 字段;

2、任务首次入队时,scheduled_at 设置为 steady_clock::now() + base_delay;

3、执行失败时,若 retry_count

4、重试任务入队前,优先级自动提升一级(但不超过 HIGHEST),防止重试被长期压在低优队列底部;

5、所有 RetryTask 共享一个 std::unordered_set<:uintptr_t> active_ids,用于 cancel_by_id() 快速查找;

6、cancel_by_id() 调用时,不仅设置 cancelled = true,还从对应队列中移除该任务(需持有对应 mutex);

7、调度器在 process_one() 中对每个任务执行前,检查 active_ids 是否仍包含其地址,若否,则跳过执行并清理元数据。

C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!

相关专题

更多
c++和c语言的区别有哪些
c++和c语言的区别有哪些

c++和c语言的区别:1、面向对象编程(OOP)支持不同;2、新增特性不同;3、标准库不同;4、编译方式不同;5、命名空间不同等等。想了解更多c++的相关内容,可以阅读本专题下面的文章。

2024.03.14

2248

9

c++和python学习顺序推荐
c++和python学习顺序推荐

一般建议先学习C++,再学习Python,因为这样可以逐步从较为底层的编程语言向更高级的语言过渡。想了解更多python的相关内容,可以阅读本专题下面的文章。

2024.03.14

1019

6

python和c++学习性价比分析
python和c++学习性价比分析

Python易于学习,广泛应用于Web开发、数据科学和人工智能等领域,但性能较低。C语言性能高,适用于对性能要求较高的场景,如游戏开发和系统编程,但学习曲线陡峭,错误处理复杂。想了解更多python的相关内容,可以阅读本专题下面的文章。

2024.03.14

427

5

c语言和c++一样吗
c语言和c++一样吗

c语言和c++是两种不同的编程语言,虽然有相似之处,但存在显著差异。c语言专注于过程式编程和系统级开发,以简洁、高效著称。c++作为c语言的超集,引入了面向对象编程,增强了代码组织和管理能力,但学习曲线也更陡峭。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.03.14

327

5

c语言和c++先学哪个好
c语言和c++先学哪个好

初学者选择学习c语言还是c++语言,需要根据个人学习目标、背景以及编程兴趣和预期应用方向来决定。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.03.14

406

5

c语言和c++的区别和联系
c语言和c++的区别和联系

c语言和c++是计算机科学领域应用广泛的编程语言。虽然它们有着相似的基础,但它们在语言类型、语法功能和内存管理方面存在着显著差异。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.03.14

580

5

c++软件中文更改教程
c++软件中文更改教程

对于 ide,可通过打开设置,找到语言设置,选择中文,并保存更改。对于非 ide 应用程序,可查找设置或选项,选择语言设置,更改为中文,并保存更改。想了解更多c++的相关内容,可以阅读本专题下面的文章。

2024.03.21

1409

9

python和java和c++学习性价比分析
python和java和c++学习性价比分析

Python以其易学性、丰富的库和活跃的社区而著称,适合数据科学、人工智能和Web开发。Java以其跨平台性、企业级应用开发和Android应用开发而闻名。C++以其底层控制能力、高效性能和游戏开发而著称。选择哪种语言取决于个人兴趣、职业方向和特定需求。想了解更多python和java和c++的相关内容,可以阅读本专题下面的文章。

2024.03.22

1217

7

c++和c语言学习顺序推荐
c++和c语言学习顺序推荐

对于初学者,建议先学习C语言,掌握编程基础后再转入C++,便于理解面向对象编程概念。有编程经验者可直接学习C++,快速接触高级编程技术。想了解更多c++和c语言的相关内容,可以阅读本专题下面的文章。

2024.03.25

1325

9

热门下载

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

精品课程

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

共0课时 | 0人学习

C++ Reference
C++ Reference

共0课时 | 0人学习

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

共0课时 | 0人学习