在 C++ 中,使用 std::atomic<int>
可以安全地进行多线程中的累加操作。std::atomic
提供了一种无锁的机制来保证对变量的并发访问是安全的。对于整数类型的累加,可以使用 fetch_add
方法。
下面是一个示例代码,展示了如何在多个线程中使用 std::atomic<int>
来实现安全的累加:
#include <iostream>
#include <thread>
#include <vector>
#include <atomic>
std::atomic<int> counter(0); // 初始化一个 atomic 整数
void increment(int numIncrements) {
for (int i = 0; i < numIncrements; ++i) {
counter.fetch_add(1); // 安全地将 counter 加 1
}
}
int main() {
const int numThreads = 10;
const int incrementsPerThread = 100;
std::vector<std::thread> threads;
// 创建多个线程
for (int i = 0; i < numThreads; ++i) {
threads.emplace_back(increment, incrementsPerThread);
}
// 等待所有线程完成
for (auto& thread : threads) {
thread.join();
}
std::cout << "Final counter value: " << counter.load() << std::endl; // 输出最终计数器值
return 0;
}
代码说明:
- 定义原子变量:使用
std::atomic<int>
定义一个原子整数counter
,并初始化为 0。 - 增量函数:
increment
函数接收要增加的次数,并在循环中调用fetch_add(1)
来安全地将计数器加 1。fetch_add
是一个原子操作,确保即使在多个线程同时调用时,也不会产生数据竞争。 - 创建和运行线程:主函数中创建了多个线程,每个线程都会执行
increment
函数。 - 等待线程完成:通过调用每个线程的
join()
方法来等待它们结束执行。 - 输出结果:最后,通过调用
load()
获取最终计数器的值并输出。
注意事项:
- 使用
std::atomic<T>
可以避免复杂性带来的错误,因为它不需要显式锁定(例如互斥量),而是通过底层硬件提供的原子操作来保证安全性。 - 对于简单累加操作,如本示例中的情况,推荐使用原子类型以提高性能和简化代码。如果有更复杂的数据结构或逻辑,则可能需要考虑其他同步机制(如互斥锁)。
内容由零声教学AI助手提供,问题来源于学员提问