std :: atomic <uint_least8_t>行为

时间:2018-05-01 16:17:20

标签: c++ c++17

在具有以下内容的系统上

typedef unsigned char      uint8_t;
typedef unsigned short     uint16_t;

std::atomic<uint8_t>::is_always_lock_free // => false
std::atomic<uint16_t>::is_always_lock_free // => true

根据我的理解,类型

std::atomic<uint_least8_t>

将是8位而不是无锁。

如果是这样的话,如果我想要一个至少8位的原子类型并且总是锁定自由,我该怎么写? (假设存在这种类型)是否有更好的替代方案:

std::atomic<
    typename std::conditional<
        std::atomic<uint8_t>::is_always_lock_free, 
        uint8_t, 
        uint16_t
    >::type
>

(为简单起见,我没有包含代码if std::atomic&lt;uint16_t>不能锁定)

1 个答案:

答案 0 :(得分:1)

模板的东西有点乱,但是它的使用非常直观:

#include <atomic>
#include <cstdint>
#include <iostream>

template <typename T, typename... others>
class first_lockfree
{
    // forward declare internal template
    template <bool, typename...> struct cond;

    // use this if is_always_lock_free == true
    template <typename condT, typename... condTs>
    struct cond<true, condT, condTs...>
    {
        // use first template argument as it is_always_lock_free
        using type = condT;
    };

    // use this if is_always_lock_free == false
    template <typename condT, typename... condTs>
    struct cond<false, condT, condTs...>
    {
        // use main template with first template parameter removed
        using type = typename first_lockfree<condTs...>::type;
    };

public:
    using type =typename cond<std::atomic<T>::is_always_lock_free, T, others...>::type;
};


int main(int, char**)
{
    using uint8_lockfree_t = first_lockfree<std::uint8_t, std::uint16_t, std::uint32_t, std::uint64_t>::type;

    std::cout <<  sizeof(uint8_lockfree_t) << std::endl;

    std::cout <<  std::atomic<std::uint8_t>::is_always_lock_free << std::endl;
    std::cout <<  std::atomic<std::uint16_t>::is_always_lock_free << std::endl;
    std::cout <<  std::atomic<std::uint32_t>::is_always_lock_free << std::endl;
    std::cout <<  std::atomic<std::uint64_t>::is_always_lock_free << std::endl;

    return 0;
}