C++之std::atomic类模板原子操作应用总结(二百三十九)

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长!

优质专栏:Audio工程师进阶系列原创干货持续更新中……

人生格言: 人生从来没有捷径,只有行动才是治疗恐惧和懒惰的唯一良药.

更多原创,欢迎关注:Android系统攻城狮

欢迎关注Android系统攻城狮

1.前言

本篇目的:理解C++之std::atomic模板类函数load、store、exchange、increment、decrement、fetch_add、fetch_sub、fetch_and、fetch_or、fetch_xor用法。

std::atomic模板类作用

C++的std::atomic是一个模板类,用于实现原子操作。它提供了一种线程安全的方式来对共享数据进行操作,以避免竞态条件。

  1. 实现原子操作:std::atomic提供了一系列的成员函数,可用于对变量进行原子操作,包括读取、写入和修改。这些操作能够确保在多线程环境下,对共享数据的操作不会发生冲突或产生竞态条件。

  2. 线程同步:std::atomic提供了一种同步机制,用于保证多线程环境下的数据一致性。通过使用std::atomic的成员函数,可以实现不同线程间的同步操作,确保每个线程对共享数据的访问是有序的。

  3. 原子性操作:std::atomic操作是原子的,即不可中断的。当多个线程同时对同一个std::atomic对象进行操作时,操作会以原子的方式执行,不会出现数据不一致或异常的情况。

  4. 替代锁机制:在某些情况下,std::atomic可以替代传统的互斥锁机制。使用std::atomic进行原子操作,可以避免锁的开销和线程等待的问题,从而提高程序的性能。

std::atomic的作用是提供一种线程安全的方式来操作共享数据,保证数据的一致性和原子性,避免多线程环境下的竞态条件和冲突。它是C++多线程编程中常用的工具之一。

2.std::atomic模板类函数load、store、exchange、increment、decrement、fetch_add、fetch_sub、fetch_and、fetch_or、fetch_xor介绍

  1. std::atomic模板类的成员函数(load、store、exchange、increment、decrement、fetch_add、fetch_sub、fetch_and、fetch_or、fetch_xor)的实现原理是通过使用硬件级别的支持或者特殊的指令集来实现的。

  2. 在现代的计算机架构中,通常会提供原子操作的指令,例如比较交换指令(Compare-and-Swap)或交换指令(Exchange),这些指令可以保证对共享变量的操作是原子的,不会被其他线程的操作中断或交叉。

  3. std::atomic模板类的成员函数会使用这些硬件级别的原子指令来实现原子操作。具体的实现方式可能因不同的编译器、平台和架构而有所差异,但其基本原理是一致的。

  4. 这些原子操作的作用是为了在多线程环境中实现线程安全的操作。使用原子操作可以避免竞争条件(Race Condition)的问题,在多个线程同时对共享变量进行操作时,能够确保操作的原子性,保证数据的一致性和正确性。

  5. 原子操作可以应用于各种并发编程场景,例如引用计数、无锁数据结构、自旋锁、并行算法等。通过使用std::atomic模板类提供的原子操作函数,可以方便地在多线程环境中进行原子操作,避免了需要显式加锁的复杂性和开销。

  6. std::atomic模板类的成员函数的作用是实现线程安全的原子操作,利用硬件级别的支持或者特殊的指令集,保证对共享变量的操作是原子的,避免了竞争条件的问题。这些原子操作可以应用于各种并发编程场景,提供了一种简单、高效和可靠的线程安全机制。

3.应用实例

  1. load():

    • 描述:返回当前std::atomic对象的值。
    • 用法:T load(std::memory_order order = std::memory_order_seq_cst) const noexcept;
    • 示例:
    #include 
    
    int main() {
        std::atomic<int> num(42);
        int value = num.load();
        std::cout << "Value: " << value << std::endl;
        return 0;
    }
    
  2. exchange():

    • 描述:用给定的值替换std::atomic对象的值,并返回替换之前的值。
    • 用法:T exchange(T desired, std::memory_order order = std::memory_order_seq_cst) noexcept;
    • 示例:
    #include 
    
    int main() {
        std::atomic<int> num(42);
        int old_value = num.exchange(10);
        std::cout << "Old value: " << old_value << std::endl;
        std::cout << "New value: " << num.load() << std::endl;
        return 0;
    }
    
  3. increment():

    • 描述:将std::atomic对象的值递增1,并返回递增之前的值。
    • 用法:T increment(std::memory_order order = std::memory_order_seq_cst) noexcept;
    • 示例:
    #include 
    
    int main() {
        std::atomic<int> num(42);
        int old_value = num++;
        std::cout << "Old value: " << old_value << std::endl;
        std::cout << "New value: " << num.load() << std::endl;
        return 0;
    }
    
  4. decrement():

    • 描述:将std::atomic对象的值递减1,并返回递减之前的值。
    • 用法:T decrement(std::memory_order order = std::memory_order_seq_cst) noexcept;
    • 示例:
    #include 
    
    int main() {
        std::atomic<int> num(42);
        int old_value = num--;
        std::cout << "Old value: " << old_value << std::endl;
        std::cout << "New value: " << num.load() << std::endl;
        return 0;
    }
    
  5. fetch_add():

    • 描述:将给定的值加到std::atomic对象的值上,并返回加之前的值。
    • 用法:T fetch_add(T arg, std::memory_order order = std::memory_order_seq_cst) noexcept;
    • 示例:
    #include 
    
    int main() {
        std::atomic<int> num(42);
        int old_value = num.fetch_add(10);
        std::cout << "Old value: " << old_value << std::endl;
        std::cout << "New value: " << num.load() << std::endl;
        return 0;
    }
    
  6. fetch_sub():

    • 描述:将给定的值从std::atomic对象的值中减去,并返回减之前的值。
    • 用法:T fetch_sub(T arg, std::memory_order order = std::memory_order_seq_cst) noexcept;
    • 示例:
    #include 
    
    int main() {
        std::atomic<int> num(42);
        int old_value = num.fetch_sub(10);
        std::cout << "Old value: " << old_value << std::endl;
        std::cout << "New value: " << num.load() << std::endl;
        return 0;
    }
    
  7. fetch_and():

    • 描述:将std::atomic对象的值与给定的值进行按位与操作,并返回按位与之前的值。
    • 用法:T fetch_and(T arg, std::memory_order order = std::memory_order_seq_cst) noexcept;
    • 示例:
    #include 
    
    int main() {
        std::atomic<int> num(42);
        int old_value = num.fetch_and(10);
        std::cout << "Old value: " << old_value << std::endl;
        std::cout << "New value: " << num.load() << std::endl;
        return 0;
    }
    
    
  8. fetch_or():

    • 描述:将std::atomic对象的值与给定的值进行按位或操作,并返回按位或之前的值。
    • 用法:T fetch_or(T arg, std::memory_order order = std::memory_order_seq_cst) noexcept;
    • 示例:
    #include 
    
    int main() {
        std::atomic<int> num(42);
        int old_value = num.fetch_or(10);
        std::cout << "Old value: " << old_value << std::endl;
        std::cout << "New value: " << num.load() << std::endl;
        return 0;
    }
    
  9. fetch_xor():

    • 描述:将std::atomic对象的值与给定的值进行按位异或操作,并返回按位异或之前的值。
    • 用法:T fetch_xor(T arg, std::memory_order order = std::memory_order_seq_cst) noexcept;
    • 示例:
    #include 
    
    int main() {
        std::atomic<int> num(42);
        int old_value = num.fetch_xor(10);
        std::cout << "Old value: " << old_value << std::endl;
        std::cout << "New value: " << num.load() << std::endl;
        return 0;
    }
    

10.store()

  • 描述:std::atomic的store函数用于将给定的值存储到std::atomic对象中。
  • 用法:template void store(T value, std::memory_order order = std::memory_order_seq_cst) noexcept;
  • 示例:
#include 
#include 

int main() {
    std::atomic<int> value;

    // 使用store函数将给定的值存储到std::atomic对象中
    value.store(42);

    // 打印存储后的值
    std::cout << "Value: " << value.load() << std::endl;

    return 0;
}

你可能感兴趣的:(C++入门系列,c++,开发语言)