[C++11] 原子变量与原子操作

        C++11中增加的官方并发支持库包含了名为<atomic>的头文件,此文件中定义了原子变量std::atomic<T>,及其各种类型特化别名atomic_boolatomic_char等。

        “原子”指的是一系列不可分割的操作或单元,它们组合在一起形成了原子操作(Atomic Operation)。这意味着在执行原子操作时,它要么完全成功,要么完全失败,没有中间状态,保证了操作的完整性。原子拥有的原子性确保了在并发编程中数据的一致性和可靠性。、

std::atomic

摘录于std::atomic - cppreference.com

类定义
定义于头文件<atomic>
template <  class T  >
struct atomic ;
(since C++11)
构造函数 
atomic ( )  noexcept  =  default ;
默认无参构造
constexpr atomic ( T desired  )  noexcept ;
使用desired初始化原子变量
atomic (  const atomic &  )  =  delete ;
显式删除拷贝构造,不允许对象间拷贝
重载operator=,不允许类外使用 = 进行对象间拷贝

T operator=( T desired ) noexcept;

T operator=( T desired ) volatile noexcept;

atomic& operator=( const atomic& ) = delete;

atomic& operator=( const atomic& ) volatile delete;

以原子方式将当前值替换为 desired ,根据 order 的值影响内存访问顺序。(默认为5)

void store( T desired, std::memory_order order = std::memory_order_seq_cst ) noexcept;

void store( T desired, std::memory_order order = std::memory_order_seq_cst ) volatile noexcept;

以原子方式加载并返回原子变量的当前值,根据order的值影响内存访问顺序。

T load( std::memory_order order = std::memory_order_seq_cst) const noexcept;

T load( std::memory_order order = std::memory_order_seq_cst ) const volatile noexcept;

内存顺序
​​​​​​​typedef enum memory_order {
    memory_order_relaxed,   // relaxed
    memory_order_consume,   // consume
    memory_order_acquire,   // acquire
    memory_order_release,   // release
    memory_order_acq_rel,   // acquire/release
    memory_order_seq_cst    // sequentially consistent
} memory_order;
检查此类型的所有对象的原子操作是否无锁,若是返回true,否则返回false

bool is_lock_free() const noexcept;

(since C++11)

bool is_lock_free() const volatile noexcept;

(since C++11)
静态成员常量,检查类型 T 是否总是无锁操作

static constexpr bool is_always_lock_free = /*implementation-defined*/;

(since C++17)

C++20新增了新的成员函数:

//wait函数:
void wait(T old,std::memory_order order = std::memory_order_seq_cst)const noexcept;

void wait(T old,std::memory_order order = std::memory_order_seq_cst)const volatile noexcept;

-------------------------------------------------------------------

//notify_one函数:
void notify_one() noexcept;

void notify_one() volatile noexcept;

-------------------------------------------------------------------

//notify_all函数:
void notify_all() noexcept;

void notify_all() volatile noexcept;

 可以通过原子类型 阻塞 / 唤醒 线程,与条件变量中的函数一样。

原子操作相比锁的优势

1. 细粒度控制:
           原子操作允许对共享数据的更细粒度控制。可以针对单个变量或数据结构的特定部分执行原子操作,而不是锁住整个数据结构或临界区。这可以减小竞争的范围,提高并发性能。

2. 低开销:
           原子操作通常比锁的开销更低。锁需要进行线程的上下文切换、调度和内核态与用户态之间的切换,而原子操作通常是在用户态执行的,避免了这些开销。

3. 避免死锁:
           锁可能导致死锁情况,其中多个线程互相等待对方释放锁资源。原子操作不会导致死锁,因为它们是无阻塞的。

4. 适用于特定问题:
           原子操作通常更适用于一些特定的问题,如计数器更新、标志位的设置或清除等简单操作。这些操作可以轻松地使用原子指令来实现,而不需要引入锁的复杂性。

5. 更容易实现和维护:
           使用原子操作的代码通常更容易实现和维护,因为无需担心锁的获取和释放、死锁、优化和调优等问题。使代码更简洁且易于理解。

        当然,并发问题多种多样,在复杂的同步问题上,锁的灵活性可能会更有优势,根据问题的不同看情况选择合适的方法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值