C++ 多线程与并发系统取向(五)—— std::atomic:原子操作与状态一致性(类比 Java Atomic)

📅 发布时间:2026/7/15 2:10:35 👁️ 浏览次数:
C++ 多线程与并发系统取向(五)—— std::atomic:原子操作与状态一致性(类比 Java Atomic)
一、先问一个核心问题前面我们已经学了mutex —— 保护共享资源condition_variable —— 线程协作那为什么还需要std::atomic因为有一种场景你不是在保护“复杂资源”你只是想保证“某个状态是安全的”二、atomic 解决什么问题atomic 解决两件事1️⃣ 避免数据竞争2️⃣ 保证可见性它适合计数器状态标志停止信号简单数值更新三、先看一个错误示例bool stop false; void worker() { while (!stop) { // do work } }主线程stop true;你以为 worker 会停⚠ 可能不会。原因编译器可能优化CPU 缓存可能导致不可见多核缓存不同步这叫内存可见性问题四、正确写法std::atomic#include atomic std::atomicbool stop(false); void worker() { while (!stop.load()) { // do work } }主线程stop.store(true);现在一定安全。五、Java 类比Java 写法volatile boolean stop false;或者AtomicBoolean stop new AtomicBoolean(false);对比JavaCvolatilestd::atomicAtomicIntegerstd::atomicint区别C 的 atomic 更底层。六、atomic 的核心特性1️⃣ 原子性Atomicity操作不会被中断。例如std::atomicint counter(0); counter;不会出现读改写被其他线程打断。2️⃣ 可见性Visibility一个线程写入后其他线程一定能看到。3️⃣ 顺序一致性默认默认使用memory_order_seq_cst保证全局一致顺序。我们暂时不深挖内存序只讲工程层七、atomic vs mutex 本质区别对比atomicmutex适合简单变量复杂资源是否阻塞不阻塞可能阻塞是否保护容器❌✅是否能替代锁❌❌一句话atomic 管“状态”mutex 管“资源”八、示例多线程计数对比错误版本int counter 0; void task() { for (int i 0; i 100000; i) { counter; } }结果不稳定。mutex 版本std::mutex mtx; int counter 0; void task() { for (int i 0; i 100000; i) { std::lock_guardstd::mutex lock(mtx); counter; } }正确但性能差。atomic 版本std::atomicint counter(0); void task() { for (int i 0; i 100000; i) { counter; } }正确且更高效。九、重要误区atomic ≠ 无锁系统很多人会说那我全用 atomic 不就行了错误。atomic 不能保护vectormapqueue多个变量组合状态例如if (x 0) { x--; }即使 x 是 atomic也可能出错。因为判断 修改 不是一个原子事务。十、工程级示例停止线程这是最常见使用场景。#include thread #include atomic #include iostream #include chrono std::atomicbool running(true); void worker() { while (running.load()) { std::cout Working... std::endl; std::this_thread::sleep_for(std::chrono::milliseconds(500)); } std::cout Stopped. std::endl; } int main() { std::thread t(worker); std::this_thread::sleep_for(std::chrono::seconds(3)); running.store(false); t.join(); }这就是atomic 做状态控制join 做生命周期管理十一、atomic 的高级形态点到为止atomic 还支持compare_exchange_strong compare_exchange_weak用于无锁算法CAS 自旋但90% 工程开发用不到。不要一上来就写 lock-free 队列。十二、系统取向思维升级现在你有四层结构1️⃣ 线程模型 —— 谁共享2️⃣ mutex —— 保护资源3️⃣ condition_variable —— 线程协作4️⃣ atomic —— 状态一致性十三、工程口诀状态用 atomic容器用 mutex等待用 condition_variable生命周期用 join十四、和 Java 再对比Javasynchronized mutexwait/notify condition_variableAtomicXXX / volatile atomicC更底层更危险更灵活十五、本篇总结一句话atomic 不是锁的替代品它是“轻量级状态同步工具”下一篇真正组合拳第六篇我们做工程实战 —— 用 mutex cv atomic 搭一个任务系统骨架可提交任务可阻塞等待可安全关闭正确释放线程这是你并发系统能力的第一块工程里程碑。