我正在尝试在结构中使用
std::atomic<uint8_t>
,期望涉及在多线程环境中存储和加载值的操作将是线程安全的。
这是我编写的测试程序。其中,每个线程都会修改不同的字段;然而,对一个字段的修改似乎也会影响
std::atomic<uint8_t>
字段:
#include <atomic>
#include <thread>
#include <iostream>
struct SimpleAtomic
{
std::atomic<uint8_t> u8;
std::atomic<uint16_t> u16;
};
int main()
{
SimpleAtomic a;
std::atomic<uint32_t> failed_u8(0), failed_u16(0);
static constexpr int times = 1000;
std::thread t1([&]()
{
for(int i = 0; i < times; i++){
a.u16.store(i);
if (a.u16 != i) failed_u16++;
} });
std::thread t2([&]()
{
for(int i = 0; i < times; i++){
a.u8.store(i);
if (a.u8 != i) failed_u8++;
} });
t1.join();
t2.join();
std::cout << "failed_u8: " << failed_u8 << std::endl;
std::cout << "failed_u16: " << failed_u16 << std::endl;
// output (ubuntu 20.04, g++ 9.3.0):
// failed_u8: 744
// failed_u16: 0
}
这不是原子性或线程安全的问题。 问题是
uint8_t
是 8 位,因此可以存储值 0..255.
在
t2
中,您尝试将 i
存储在其中,其中 i
是 0..999.
所有值 256..999.
都会失败