C++11 原子变量atomic

什么是原子变量

原子变量是在多线程访问状态下不会导致数据竞争的变量。

原子变量保证多线程安全,效率会比互斥量好一些。

主要用于无锁编程。

实现

硬件层面:通过添加原子指令以保证对单个变量操作的原子性。

软件层面:使用互斥锁或者自旋锁保证只有拥有锁的线程,变量会被该线程访问或修改。

GCC下原子变量的定义

这是一个整型模板的源码定义和成员函数

 /// Explicit specialization for int.
  template<>
    struct atomic<int> : __atomic_base<int>
    {
      typedef int 			__integral_type;
      typedef __atomic_base<int> 		__base_type;

      atomic() noexcept = default;
      ~atomic() noexcept = default;
      atomic(const atomic&) = delete;
      atomic& operator=(const atomic&) = delete;
      atomic& operator=(const atomic&) volatile = delete;

      constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }

      using __base_type::operator __integral_type;
      using __base_type::operator=;

#if __cplusplus >= 201703L
    static constexpr bool is_always_lock_free = ATOMIC_INT_LOCK_FREE == 2;
#endif
    };
bool is_lock_free() const noexcept { return _M_base.is_lock_free(); }
#if __cplusplus >= 201703L
    static constexpr bool is_always_lock_free = ATOMIC_BOOL_LOCK_FREE == 2;
#endif

    void
    store(bool __i, memory_order __m = memory_order_seq_cst) noexcept
    { _M_base.store(__i, __m); }

    bool
    load(memory_order __m = memory_order_seq_cst) const noexcept
    { return _M_base.load(__m); }

    bool
    exchange(bool __i, memory_order __m = memory_order_seq_cst) noexcept
    { return _M_base.exchange(__i, __m); }

    bool
    compare_exchange_weak(bool& __i1, bool __i2, memory_order __m1,
			  memory_order __m2) noexcept
    { return _M_base.compare_exchange_weak(__i1, __i2, __m1, __m2); 

    bool
    compare_exchange_strong(bool& __i1, bool __i2, memory_order __m1,
			    memory_order __m2) noexcept
    { return _M_base.compare_exchange_strong(__i1, __i2, __m1, __m2); }

atomic相关的成员函数

构造函数

atomic() noexcept = default;  //对象处于未初始化状态
constexpr atomic (T val) noexcept;  //使用val初始化对象
atomic (const atomic&) = delete;  //无法复制/移动对象

is_lock_free()

bool is_lock_free() const volatile noexcept;
bool is_lock_free() const noexcept;
//提示该原子对象是否为无锁对象,无锁对象不会导致其他线程在访问时被阻塞

store函数

void store (T val, memory_order sync = memory_order_seq_cst) volatile noexcept;
void store (T val, memory_order sync = memory_order_seq_cst) noexcept;
//修改包含的值,将包含的值替换为val,该操作是原子操作

std::atomic<int> foo (0);
foo.store(x,std::memory_order_relaxed);     // set value atomically
//修改值是原子操作

load函数

T load (memory_order sync = memory_order_seq_cst) const volatile noexcept;
T load (memory_order sync = memory_order_seq_cst) const noexcept;
//读取值同样是原子操作

exchange函数

T exchange (T val, memory_order sync = memory_order_seq_cst) volatile noexcept;
T exchange (T val, memory_order sync = memory_order_seq_cst) noexcept;
//用val修改原子变量包含的值,并且使用返回修改前的值。
atomic<int> x(1);
cout << x.exchange(2) << endl; // cout 1
cout << x.exchange(3) << endl; // cout 2

compare_exchange_weak函数

bool compare_exchange_weak (T& expected, T val,memory_order sync = memory_order_seq_cst) volatile noexcept;
bool compare_exchange_weak (T& expected, T val,memory_order sync = memory_order_seq_cst) noexcept;
bool compare_exchange_weak (T& expected, T val,memory_order success, memory_order failure) volatile noexcept;
bool compare_exchange_weak (T& expected, T val,memory_order success, memory_order failure) noexcept;
//比较和交换值,如果为true,则用like替换为包含的值
//false,则替换为包含的值

函数尝试更新目标值,在某些情况下可能会返回失败,即使更新已经发生了。

如果当前值等于except,则修改为val,返回成功,但有时候成功修改了也会修改为失败,这种情况称为伪失败。

memory_order_seq内存控制顺序,暂定,不是很懂。

compare_exchange_strong函数

互斥锁模拟原子变量

#include <iostream>
#include <thread>
#include <mutex>
using namespace std;
template <typename T>
class MyAtomic
{
public:
    MyAtomic(T value)
        : m_value(value)
    {
    }

    void operator=(T &ans)
    {
        m_mutex.lock();
        m_value = ans;
        m_mutex.unlock();
    }

    void operator++()
    {
        m_mutex.lock();
        m_value++;
        m_mutex.unlock();
    }

    void operator++(int)
    {
        m_mutex.lock();
        ++m_value;
        m_mutex.unlock();
    }

    // 不保证线程安全
    T getValue()
    {
        return m_value;
    }

    friend ostream &operator<<(ostream &cout, MyAtomic<T> &MAT)
    {
        cout << MAT.getValue();
        return cout;
    }

private:
    T m_value;
    mutex m_mutex;
};

template <typename T>
ostream &operator<<(ostream &cout, MyAtomic<T> &MAT)
{
    cout << MAT.getValue();
    return cout;
}

MyAtomic<int> x = 0;

void threadWorker()
{
    for (int i = 0; i < 100000; ++i)
        ++x;
}

int main()
{
    cout << min(1, 3) << endl;
    thread thread1(threadWorker);
    for (int i = 0; i < 100000; ++i)
        ++x;
    thread1.join();
    return 0;
}

  • 6
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值