c++ - 两个 std::atomic 可以成为一个 union 的一部分吗?

标签 c++ c++11 atomic

我想这样做:

union {
    std::atomic<uint128_t> u128;
    struct {
        std::atomic<uint64_t> u64_1;
        std::atomic<uint64_t> u64_2;
    };
};

多个线程将读取和写入 union 的两个部分。

安全吗?

编辑:我使用 Linux,x86_64,clang 3.3

Edit2:我希望能够递增和递减 u64_1,读取 u64_2,并写入 u128(compare_exchange)

Edit3:如果我使用 atomic builtin functions 会怎么样? ? union 将如下所示:

union {
    uint128_t u128;
    struct {
        uint64_t u64_1;
        uint64_t u64_2;
    };
};

u64_1 将映射到 u128 的前半部分,u64_2 将映射到后半部分。

最佳答案

std::atomic<T>操作可以是无锁的或锁定的,具体取决于架构是否提供底层保证。您可以通过检查 std::atomic<T>::is_lock_free() 来检查这一点.

如果类型不是无锁的,库可能会通过计数器支持它。这反过来可能意味着该类型不再是底层的 POD,这又意味着您有责任在从 union 的一个事件成员切换到另一个事件成员时调用构造函数/析构函数。

如果 128 位类型有互斥量但 64 位类型没有互斥量,您可能会遇到值布局一致的情况,但操作的原子性由不同的方式保证,因此它可能看起来有效,但会虚假地以一种甚至难以检测的方式失败。

关于c++ - 两个 std::atomic 可以成为一个 union 的一部分吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18278611/

相关文章:

c++ - 为什么变换矩阵在 OpenGL 中不起作用

c++ - 无法在 C++ 中使用类实例

c++ - C++11 中的无锁缓存实现

asp.net - 使用 MySQL、ASP.NET 和 Entityframework 实现原子计数器

c++ - 如何覆盖 std::atomic 类的默认析构函数

c++ - 引用 - const 指针

c++ - 具有成员 std::vector 的移动语义

c++ - 在 C++ 中将 csv 读入 unordered_map

c++ - 在 C++11 中双重检查锁定?

c++ - 具有单一生产者单一消费者的无锁循环缓冲区