作者yam276 (史莱哲林的优等生)
看板Marginalman
标题[闲聊] 每日C++小秘密(4):I am std::atomic
时间Wed Oct 30 18:57:06 2024
什麽是原子操作?
在多执行绪程式中,执行绪之间可能同时访问和修改共享资料。
如果没有适当的同步机制,这可能导致资料竞争和未定义行为。
我们在过去最常使用锁(如 std::mutex)来保护共享资料,
但锁可能带来性能开销和死锁风险。
原子操作提供了一种轻量级的同步方式,
允许我们在不使用锁的情况下进行安全的共享资料访问。
一段使用 std::atomic 的范例:
Code:
#include <atomic>
#include <thread>
#include <vector>
#include <iostream>
std::atomic<int> counter(0);
void increment(int numIncrements) {
for (int i = 0; i < numIncrements; ++i) {
counter.fetch_add(1, std::memory_order_relaxed);
}
}
int main() {
const int numThreads = 4;
const int numIncrements = 100000;
std::vector<std::thread> threads;
for (int i = 0; i < numThreads; ++i) {
threads.emplace_back(increment, numIncrements);
}
for (auto& t : threads) {
t.join();
}
std::cout << "Final counter value: " << counter.load() << std::endl;
// 最终 counter 的值应该是 numThreads * numIncrements
return 0;
}
C++中的 std::atomic
C++11 引入了标准库 <atomic>,提供了一组模板类别和函数,用於实现原子操作。
std::atomic 是一个模板类别,可以包装基本类别或自定义类别,使其操作具有原子性。
原子操作的原理就是确保不会同时有第二个执行绪存取资源,而之所以被称为
原子操作,
也是因为原子作为最小不可分割的个体(一般常识上,请忽略夸克等更小的基本粒子),
只要是std::atomic支援的型别与原子性的操作(如store、load、exchange或是运算符号
++,–,+=,-=,&=,|=,^= 等等)就可以进行无锁操作,
但不包含这种单一操作多次使用:
Code:
if (atomicVar.load() == expectedValue) {
atomicVar.store(newValue);
}
因为在 load 与 store 中间可能会有其他原子操作出现。
另外要注意的是记忆体顺序(memory_order),
因为原子操作可能为了更高效能使用较脆弱的记忆体顺序(如 memory_order_relaxed)
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 60.248.143.163 (台湾)
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/Marginalman/M.1730285828.A.B2F.html
※ 编辑: yam276 (60.248.143.163 台湾), 10/30/2024 18:57:20
1F:→ cities516: I am atomic 10/30 18:57
2F:推 sustainer123: 我最近也有看到py的原子操作 10/30 18:58
3F:→ ILoveErr: 大师 10/30 18:59
4F:→ yam276: 用PY进行操作 好色喔 10/30 18:59
5F:推 DJYOMIYAHINA: 大师 10/30 19:08
6F:推 wangyc: 原子小金刚 10/30 19:09
7F:→ rainkaras: 真不愧是C++大人 10/30 19:23
8F:推 oin1104: 大师 10/30 20:39