C++ 多线程与并发系统取向(六)—— 任务系统骨架:mutex + condition_variable + atomic 组合实战

一、目标:做一个“可用”的最小任务系统

我们要实现一个简化版任务系统,支持:

  • ✅ 提交任务(任意函数)
  • ✅ 工作线程自动执行
  • ✅ 无任务时阻塞等待
  • ✅ 支持安全关闭
  • ✅ 正确释放线程

你可以理解为:

线程池的前身。

二、设计思路(系统取向)

我们需要三类能力:


1️⃣ 资源保护(队列)

  • 任务队列
  • 多线程访问
  • 必须用 mutex 保护

2️⃣ 线程协作(等待任务)

  • 队列空 → 线程休眠
  • 新任务 → 唤醒线程
  • 使用 condition_variable

3️⃣ 状态控制(停止系统)

  • 停止标志
  • 使用 atomic<bool>

三、整体结构图

主线程 │ ├── submit() → push 任务 → notify │ ▼ 工作线程 │ ├── wait 等待任务 ├── 取任务 ├── unlock ├── 执行 └── 循环

四、完整实现(可直接运行)

1️⃣ 头文件

#include <iostream> #include <thread> #include <vector> #include <queue> #include <mutex> #include <condition_variable> #include <atomic> #include <functional>

2️⃣ 任务系统类

class TaskSystem { public: TaskSystem(size_t threadCount) : running_(true) { for (size_t i = 0; i < threadCount; ++i) { workers_.emplace_back([this] { this->workerLoop(); }); } } ~TaskSystem() { shutdown(); } // 提交任务 void submit(std::function<void()> task) { { std::unique_lock<std::mutex> lock(mtx_); tasks_.push(task); } cv_.notify_one(); } // 关闭系统 void shutdown() { running_.store(false); cv_.notify_all(); for (auto& t : workers_) { if (t.joinable()) { t.join(); } } } private: void workerLoop() { while (true) { std::function<void()> task; { std::unique_lock<std::mutex> lock(mtx_); cv_.wait(lock, [this] { return !tasks_.empty() || !running_.load(); }); if (!running_.load() && tasks_.empty()) { return; } task = tasks_.front(); tasks_.pop(); } task(); // 在锁外执行任务 } } private: std::vector<std::thread> workers_; std::queue<std::function<void()>> tasks_; std::mutex mtx_; std::condition_variable cv_; std::atomic<bool> running_; };

五、测试代码

int main() { TaskSystem pool(3); for (int i = 0; i < 10; ++i) { pool.submit([i] { std::cout << "Task " << i << " running in thread " << std::this_thread::get_id() << std::endl; }); } std::this_thread::sleep_for(std::chrono::seconds(1)); pool.shutdown(); return 0; }

输出类似:

Task 0 running in thread 1234 Task 1 running in thread 5678 ...

六、关键点逐条拆解(非常重要)


1️⃣ 为什么 running_ 用 atomic?

因为:

  • 多线程读写
  • 只控制“状态”
  • 不涉及复杂资源

符合 atomic 使用场景。

2️⃣ 为什么任务执行必须在锁外?

如果这样写:

task();

放在锁内:

  • 所有线程会被阻塞
  • 并发能力消失

原则:

锁保护资源,不保护业务逻辑

3️⃣ 为什么 wait 要带 predicate?

cv_.wait(lock, condition);

防止:

  • 假唤醒
  • 丢通知

4️⃣ 为什么 shutdown 要 notify_all?

因为:

  • 可能多个线程在等待
  • 必须全部唤醒退出

七、Java 类比

Java 线程池:

ExecutorService pool = Executors.newFixedThreadPool(3); pool.submit(() -> {}); pool.shutdown();

Java 帮你封装了:

  • 任务队列
  • 条件变量
  • 状态控制

C++:

你自己写。

这就是 C++ 并发“系统级能力”的核心差异。

八、系统层面你已经掌握了什么?

现在你已经具备:

✔ 线程模型理解

谁共享数据?

✔ 资源保护

mutex + RAII

✔ 线程协作

condition_variable

✔ 状态控制

atomic

✔ 生命周期管理

join + shutdown

九、工程升级方向(后续可以做)

  • 支持有界队列
  • 支持优先级任务
  • 支持 future
  • 支持返回值
  • 支持任务取消

十、本篇总结口诀

队列用 mutex
等待用 cv
状态用 atomic
生命周期用 join

十一、下一篇(最终篇)

第七篇我们讲:

并发排障与工程纪律

  • 死锁四条件
  • 锁顺序策略
  • 竞态如何定位
  • 性能如何优化
  • 锁粒度怎么拆
  • 工程规范 checklist

这才是“系统取向”的终章。

Read more

MySQL查看命令速查表

MySQL查看命令速查表

🎬 个人主页:艾莉丝努力练剑 ❄专栏传送门:《C语言》《数据结构与算法》《C/C++干货分享&学习过程记录》 《Linux操作系统编程详解》《笔试/面试常见算法:从基础到进阶》《Python干货分享》 ⭐️为天地立心,为生民立命,为往圣继绝学,为万世开太平 🎬 艾莉丝的简介: 文章目录 * 1 ~> MySQL 查看类命令大全 * 1.1 查看数据库 * 1.2 查看表 * 1.3 查看数 * 1.4 查看用户 / 权限 * 1.5 最常用组合(截图里就是这套) * 2 ~> MySQL常用核心命令速查表 * 2.1 MySQL 常用核心命令速查表 * 2.

By Ne0inhk
Flutter 组件 highlighter 适配鸿蒙 HarmonyOS 实战:高性能语法高亮,构建大规模代码分析与文本染色架构

Flutter 组件 highlighter 适配鸿蒙 HarmonyOS 实战:高性能语法高亮,构建大规模代码分析与文本染色架构

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net Flutter 组件 highlighter 适配鸿蒙 HarmonyOS 实战:高性能语法高亮,构建大规模代码分析与文本染色架构 前言 在鸿蒙(OpenHarmony)生态迈向专业化工具链、涉及海量日志审计、在线编程教育及开发者社区分发的背景下,如何为长篇累牍的源代码实现毫秒级的语法高亮与结构化展示,已成为决定用户阅读体验与知识传递效率的“视觉分水岭”。在鸿蒙设备这类强调 AOT 极致性能与复杂文本排版(Text Layout)的环境下,如果应用依然依赖基础的正则表达式进行低效的字符匹配,由于由于解析算法的复杂性,极易由于由于“主线程阻塞”导致大型文件在滑动过程中产生严重的掉帧与视觉黏连。 我们需要一种能够支持多语言语法解析、具备词法分析(Lexing)深度且兼容 RichText 富文本输出的高性能染色方案。 highlighter 为 Flutter 开发者引入了基于标准词法字典的语法高亮引擎。它不仅能精准识别不同编程语言的关键字、操作符与注释,更利

By Ne0inhk
【前端小站】HTML 标签:网页骨架,从空白到惊艳,全靠这些 HTML 标签搞事情

【前端小站】HTML 标签:网页骨架,从空白到惊艳,全靠这些 HTML 标签搞事情

半桔:个人主页  🔥 个人专栏: 《前端扫盲》《手撕面试算法》《C++从入门到入土》 🔖为什么有人总是赞美生活的丰富多彩?我想这是因为他们善于品尝生活中随时出现的意外。 -余华- 文章目录 * 前言 * 一. HTML结构 * 1.1 初始HTML标签 * 1.2 标签的层次 * 二. HTML文本标签 * 2.1 标题标签 * 2.2 段落标签 * 2.3 强调标签 * 2.3.1 加粗 * 2.3.2 倾斜 * 2.3.3 删除线 * 2.3.4 下划线 * 三. 媒体与交互标签 * 3.

By Ne0inhk
一文让你测底明白如何在 Spring Boot 上传中将 MultipartFile 转 File 对象

一文让你测底明白如何在 Spring Boot 上传中将 MultipartFile 转 File 对象

🌷 古之立大事者,不惟有超世之才,亦必有坚忍不拔之志 🎐 个人CSND主页——Micro麦可乐的博客 🐥《Docker实操教程》专栏以最新的Centos版本为基础进行Docker实操教程,入门到实战 🌺《RabbitMQ》专栏19年编写主要介绍使用JAVA开发RabbitMQ的系列教程,从基础知识到项目实战 🌸《设计模式》专栏以实际的生活场景为案例进行讲解,让大家对设计模式有一个更清晰的理解 🌛《开源项目》本专栏主要介绍目前热门的开源项目,带大家快速了解并轻松上手使用 🍎 《前端技术》专栏以实战为主介绍日常开发中前端应用的一些功能以及技巧,均附有完整的代码示例 ✨《开发技巧》本专栏包含了各种系统的设计原理以及注意事项,并分享一些日常开发的功能小技巧 💕《Jenkins实战》专栏主要介绍Jenkins+Docker的实战教程,让你快速掌握项目CI/CD,是2024年最新的实战教程 🌞《Spring Boot》专栏主要介绍我们日常工作项目中经常应用到的功能以及技巧,代码样例完整 👍《Spring Security》专栏中我们将逐步深入Spring Security的各个

By Ne0inhk