缘由
在需要进行并发编程的多线程应用中,std::atomic
会被广泛使用。
用法
load()
:从原子对象中加载当前值。
#include <iostream>
#include <atomic>
int main() {
std::atomic<int> value(10);
int loadedValue = value.load();
std::cout << "Loaded value: " << loadedValue << std::endl;
return 0;
}
store(val)
:将给定的值存储到原子对象中。
#include <iostream>
#include <atomic>
int main() {
std::atomic<int> value;
value.store(20);
std::cout << "Stored value: " << value << std::endl;
return 0;
}
exchange(val)
:交换原子对象中的值,并返回之前的值。
#include <iostream>
#include <atomic>
int main() {
std::atomic<int> value(30);
int oldValue = value.exchange(40);
std::cout << "Exchanged value: " << oldValue << std::endl;
std::cout << "New value: " << value << std::endl;
return 0;
}
compare_exchange_weak(expected, desired)
和compare_exchange_strong(expected, desired)
:比较原子对象的当前值和期望值,如果相等则用新值替换当前值。
#include <iostream>
#include <atomic>
int main() {
std::atomic<int> value(50);
int expected = 50;
int desired = 60;
bool success = value.compare_exchange_weak(expected, desired);
if (success) {
std::cout << "Compare_exchange successful. New value: " << value << std::endl;
} else {
std::cout << "Compare_exchange failed. Current value: " << value << std::endl;
}
return 0;
}
fetch_add(val)
和fetch_sub(val)
:分别对原子对象的值进行加法和减法操作,并返回操作之前的值。
#include <iostream>
#include <atomic>
int main() {
std::atomic<int> value(70);
int oldValue = value.fetch_add(5);
std::cout << "Old value: " << oldValue << std::endl;
std::cout << "New value: " << value << std::endl;
return 0;
}
fetch_and(val)
、fetch_or(val)
和fetch_xor(val)
:分别对原子对象的值进行按位与、按位或和按位异或操作,并返回操作之前的值。
#include <iostream>
#include <atomic>
int main() {
std::atomic<int> value(15);
int oldValue = value.fetch_and(3);
std::cout << "Old value: " << oldValue << std::endl;
std::cout << "New value: " << value << std::endl;
return 0;
}
作用
- 保证原子性操作:
std::atomic
可以确保基本的内存读取、写入和其他操作是原子的,这意味着在多线程环境下,对std::atomic
类型的对象进行操作时不会发生数据竞争,从而避免了需要额外的锁来保护这些操作的情况。 - 提供内存顺序保证:
std::atomic
也提供了内存顺序保证,确保所有线程都能够看到相同的操作顺序,从而避免了由于指令重排等导致的意外行为。 - 用于并发数据结构:
std::atomic
在开发并发数据结构时非常有用,比如并发队列、栈、哈希表等,它可以确保在多线程环境下对这些数据结构的操作是线程安全的。最好还是用lock_guard搭配mutex来处理vector等STL容器。 - 提高性能:相比使用锁(如互斥锁)来进行同步,
std::atomic
可能在某些情况下具有更好的性能,特别是对于一些简单的操作,因为它们不涉及线程的阻塞和唤醒。
发表回复