这是一个使用 C++11 实现的教学型运行时仓库,目标不是一次性给出“最终版线程池”,而是通过一条可以逐步阅读、逐步验证的 Git 历史,展示一个线程池如何从最基础的实现,演进到接近 CGraph 风格的运行时,再进一步支撑 DAG 调度框架。
这个仓库最重要的不是某一个最终文件,而是这条演进路径本身。
如果你直接看 main,你会看到一个已经具备如下能力的实现:
- 主工作线程与辅助工作线程并存
- 主工作线程之间支持 work stealing
- 同时存在全局队列与优先级队列
- 支持监控线程按负载扩缩辅助线程
- 支持
std::future风格任务提交 - 支持
TaskGroup形式的批量任务提交 - 支持 DAG 建图、校验、动态调度执行与 DOT 导出
但如果你想真正理解它为什么会变成现在这个样子,应该按阶段分支来读,而不是一上来就扎进最终代码里。
- docs/EVOLUTION.md:总览文档,包含阶段对比表、阅读顺序、演进逻辑、建议 diff 路径
- docs/stages/v1-basic-thread-pool.md:最基础线程池阶段说明
- docs/stages/v2-pool-queue-refactor.md:模块拆分阶段说明
- docs/stages/v3-work-stealing.md:本地队列与 work stealing 阶段说明
- docs/stages/v4-priority-secondary.md:优先级队列与辅助线程阶段说明
- docs/stages/v5-monitor-routing.md:监控线程与动态路由阶段说明
- docs/stages/v6-dag-runtime.md:DAG 运行时阶段说明
建议不要直接从 main 开始逐个文件读,而是按照下面的顺序切换分支:
git checkout v1-basic-thread-pool
git checkout v2-pool-queue-refactor
git checkout v3-work-stealing
git checkout v4-priority-secondary
git checkout v5-monitor-routing
git checkout v6-dag-runtime每切换到一个分支,建议做三件事:
- 先读对应阶段文档,理解这一版想解决什么问题。
- 再看这一版最关键的 3 到 5 个头文件与实现文件。
- 最后运行测试和示例,确认你理解到的是“真实行为”,而不是纸面结构。
这条演进链试图回答下面几类问题:
最基础的线程池其实并不复杂:
- 固定数量线程
- 一个共享任务队列
- 一个阻塞等待机制
- 一个安全退出机制
- 一个能返回结果的提交接口
但是,能跑不代表可扩展。很多后续复杂度,其实都是为了处理真实运行时中的“非对称压力”。
当任务负载不均匀时,单全局队列容易成为锁竞争中心; 当某个 worker 被定向打满时,其他 worker 可能闲着; 当不同类型任务混在一起时,重要任务可能被普通任务淹没; 当系统负载是动态变化的,固定线程数又会出现“高峰不够、低峰浪费”的问题。
换句话说,后续的 work stealing、priority queue、secondary worker、monitor,并不是为了“炫技”,而是为了逐步解决这些具体的运行时问题。
很多人第一次做图调度时,容易把“线程池调度”和“图依赖调度”揉成一个东西。但这会让系统边界越来越混乱。
本仓库在 v6 的设计选择是:
- 线程池只关心“任务如何执行”
- DAG 层只关心“节点何时就绪、何时该被提交”
- 两者之间通过一个窄接口适配,而不是互相侵入内部细节
这个边界非常重要。它决定了后续你既可以单独复用线程池,也可以替换 DAG 引擎,而不需要把整套运行时一起推翻。
cmake -S . -B build
cmake --build build
ctest --test-dir build --output-on-failure如果你在 main 上,还可以运行示例:
./build/examples/thread_pool_example
./build/examples/dag_demo如果你的目标不是“跑起来”,而是“真正理解”,建议使用下面的对照方式:
先看这些公共入口:
- 线程池入口:include/thread_pool/pool/thread_pool.h
- DAG 入口:include/thread_pool/dag/dag_executor.h
- 配置入口:include/thread_pool/core/thread_pool_config.h
再看这些核心实现:
- 线程池实现:src/pool/thread_pool.cpp
- 主 worker:src/worker/primary_worker.cpp
- 辅助 worker:src/worker/secondary_worker.cpp
- DAG 动态引擎:src/dag/dynamic_dag_engine.cpp
测试文件其实是最好的“行为说明书”:
- 线程池测试:tests/thread_pool_tests.cpp
- DAG 运行时测试:tests/dag_runtime_test.cpp
这个仓库不是一个“给你答案”的线程池项目,而是一个“把答案拆成六步给你看”的线程池与 DAG 运行时演进项目。