首页 > 后端开发 > C++ > 正文

C++如何使用std::atomic_C++原子操作与多线程安全实践

尼克
发布: 2025-11-20 14:05:02
原创
170人浏览过
std::atomic是C++11引入的模板类,用于保证对基本类型的读写操作具有原子性,避免多线程下的数据竞争。它通过提供load、store、fetch_add、exchange和compare_exchange_weak/strong等原子操作,实现无锁并发控制。相比互斥锁,std::atomic性能更高,适用于计数器、标志位同步等场景。配合内存序(如memory_order_relaxed、acquire、release、seq_cst)可精细控制操作顺序与可见性。例如用fetch_add可安全递增共享计数器,用release/acquire确保跨线程内存访问顺序,用CAS实现无锁栈或队列。正确使用需理解其内存模型,防止因误配内存序导致隐蔽错误。

c++如何使用std::atomic_c++原子操作与多线程安全实践

在C++多线程编程中,数据竞争是常见问题。当多个线程同时读写同一变量时,如果没有同步机制,程序行为将不可预测。std::atomic 提供了一种轻量级、高效的解决方案,确保对特定类型的操作是原子的,从而避免使用互斥锁(mutex)带来的性能开销。

什么是 std::atomic

std::atomic 是 C++11 引入的一个模板类,用于封装基本数据类型(如 int、bool、指针等),保证对其的操作是原子的。这意味着在多线程环境下,读取或修改该变量不会出现中间状态,也不会引发数据竞争。

常见的原子类型包括:

  • std::atomic<int>
  • std::atomic<bool>
  • std::atomic<long>
  • std::atomic<T*>(原子指针)

例如,定义一个原子整数:

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

std::atomic counter{0};

原子操作的基本用法

std::atomic 支持多种操作,最常用的是 load、store、fetch_add、exchange 和 compare_exchange_weak/strong。

示例:多线程递增计数器

#include <atomic>
#include <thread>
#include <vector>

std::atomic count{0};

void increment() {
for (int i = 0; i < 1000; ++i) {
count.fetch_add(1, std::memory_order_relaxed);
}
}

int main() {
std::vector<std::thread> threads;
for (int i = 0; i < 10; ++i) {
threads.emplace_back(increment);
}

for (auto& t : threads) {
t.join();
}

// 结果一定是 10000
return 0;
}

这里使用 fetch_add 原子地增加计数器值,即使多个线程同时调用,最终结果也正确。

Logome
Logome

AI驱动的Logo生成工具

Logome 133
查看详情 Logome

内存序(Memory Order)的选择

std::atomic 操作可以指定内存顺序,控制操作的可见性和同步行为。常用的有:

  • std::memory_order_relaxed:只保证原子性,不保证顺序。适合计数器等无需同步场景。
  • std::memory_order_acquire:用于读操作,确保后续读写不会被重排到该操作之前。
  • std::memory_order_release:用于写操作,确保前面的读写不会被重排到该操作之后。
  • std::memory_order_acq_rel:同时具备 acquire 和 release 语义。
  • std::memory_order_seq_cst:默认选项,提供最严格的顺序一致性,性能稍低。

例如,实现自旋锁或标志位同步时,可使用 acquire/release 来减少开销:

std::atomic ready{false};
int data = 0;

// 线程1:
data = 42;
ready.store(true, std::memory_order_release); // 保证 data 写入在 store 前完成

// 线程2:
while (!ready.load(std::memory_order_acquire)) {
// 自旋等待
}
// 此时能安全读取 data
assert(data == 42);

compare-and-swap 与无锁编程

compare_exchange_weak 和 compare_exchange_strong 实现了 CAS(Compare and Swap)操作,是构建无锁数据结构的基础。

典型用法:

std::atomic value{0};
int expected = value.load();
do {
int desired = expected + 1;
} while (!value.compare_exchange_weak(expected, desired));

这段代码尝试将 value 原子地加 1。如果期间被其他线程修改,expected 会更新为当前值,循环继续尝试,直到成功。

CAS 常用于实现无锁、队列等结构,避免锁竞争,提升并发性能。

基本上就这些。std::atomic 是多线程编程中的重要工具,合理使用能显著提高程序效率和安全性。关键是理解原子操作的语义和内存模型,避免误用导致隐蔽 bug。

以上就是C++如何使用std::atomic_C++原子操作与多线程安全实践的详细内容,更多请关注php中文网其它相关文章!

最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号