目录
1 概述
原子类型是封装一个值的类型,该值的访问保证不会导致数据争用,并且可以用于同步不同线程之间的内存访问。
这个头文件(atomic)声明了两个C++类,atomic和atomic_flag,它们在自包含类中实现原子类型的所有特性。头文件(atomic)还声明了一整套与C中的原子支持兼容的C样式类型和函数。
其类图:
2 使用实例
2.1 atomic
原子类型是一个模板类,其对象包含特定类型(T)的值。
原子对象的主要特征是,从不同线程访问此包含的值不会导致数据竞争(即,这样做是定义明确的行为,访问顺序正确)。一般来说,对于所有其他对象,导致同时访问同一对象的数据竞争的可能性将该操作限定为未定义的行为。
此外,原子对象能够通过指定不同的内存顺序来同步对其线程中其他非原子对象的访问。
struct Function4StoreAndLoad
{
std::atomic<int> value{
0};
void set_value(int x)
{
value.store(x, std::memory_order_relaxed);
}
void print_value()
{
int x;
do{
x = value.load(std::memory_order_relaxed);
}while(x == 0);
std::cerr << "\nvalue: " << value << std::endl;
}
};
void AtomicSuite::store()
{
Function4StoreAndLoad function;
std::thread a(&Function4StoreAndLoad::print_value, std::ref(function));
std::thread b(&Function4StoreAndLoad::set_value, std::ref(function), 20);
a.join();
b.join();
TEST_ASSERT_EQUALS(20, function.value)
}
2.2 atomic_flag
原子标志是布尔原子对象,支持两种操作:测试并设置(test_and_set)和清除(clear)。
原子标志是无锁的(这是唯一保证在所有库实现上无锁的类型)。
struct Function4AtomicFlag
{
std::atomic_flag lock_stream{
ATOMIC_FLAG_INIT};
std::stringstream stream;
int counter = 0;
void append_number(int x)
{
while(lock_stream.test_and_set())
{
std::cerr << "stream is locked\n";
}
stream << "thread #" << x << std::endl;
counter++;
lock_stream.clear();
}
void print_stream()
{
std::cerr << "\n" << stream.str();
}
};
void AtomicSuite::atomic_flag()
{
Function4AtomicFlag fucntion;
std::vector<std::thread> threads;
threads.reserve(10);
for(