C++之std::atomic<bool>原子bool类型与普通bool区别(二百六十二)

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

优质专栏:Audio工程师进阶系列原创干货持续更新中……】🚀
优质专栏:多媒体系统工程师系列原创干货持续更新中……】🚀

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

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

欢迎关注Android系统攻城狮

1.前言

本篇目的:C++之std::atomic原子bool类型与普通bool区别

2.std::atomic原子bool类型与普通bool区别介绍

  • std::atomic 是 C++11 标准库中的一个模板特化,用于表示一个可以原子操作的布尔值。原子操作意味着这些操作是不可中断的,即在多线程环境中,当一个线程正在执行原子操作时,其他线程无法同时访问或修改这个值。

  • 与普通的 bool 类型相比,std::atomic 有以下主要区别和用途:

  • 线程安全:普通的 bool 类型不是线程安全的。如果你在多线程环境中共享一个普通的 bool 变量,并且多个线程可能会同时读取或修改它,那么你需要额外的同步机制(如互斥锁)来避免数据竞争和不一致。而 std::atomic 提供了内建的线程安全保证,无需额外的同步。

  • 原子操作:你可以对 std::atomic 执行原子操作,如 load(), store(), exchange(), compare_exchange_weak(), 和 compare_exchange_strong()。这些操作在多线程环境中是安全的,因为它们在执行时不会被其他线程打断。相比之下,对普通的 bool 的操作(如赋值或读取)通常不是原子的,因此在多线程环境中可能导致问题。

  • 性能:虽然使用 std::atomic 通常比使用互斥锁等同步机制有更高的性能开销,但在某些情况下,它仍然是一个很好的选择。特别是当需要频繁地、快速地访问和修改共享数据时,原子类型可以提供一个相对高效的解决方案,同时保持线程安全。

  • 简化的同步:使用 std::atomic 可以简化代码,因为你不需要显式地管理锁或其他同步机制。这可以使代码更易于理解和维护。

  • 一个典型的 std::atomic 的使用场景是在多线程环境中作为一个标志位或信号量。例如,一个线程可以原子地设置一个 std::atomic 变量来表示某个任务已经完成,而另一个线程可以原子地检查这个变量来确定是否应该继续执行后续操作。

3.代码实例

<1>.普通bool例子:多线程中的非原子操作(可能导致数据竞争)

#include <iostream>  
#include <thread>  
#include <chrono>  
  
bool ready = false; // 非原子布尔变量  
  
void workerThread() {  
    std::this_thread::sleep_for(std::chrono::seconds(1));  
    ready = true; // 非原子地设置 ready 为 true  
}  
  
void waitForSignal() {  
    while (!ready) {  
        std::cout << "Waiting for the signal...\n";  
        std::this_thread::sleep_for(std::chrono::milliseconds(100)); // 等待信号  
    }  
    std::cout << "Received the signal!\n";  
}  
  
int main() {  
    std::thread worker(workerThread);  
    waitForSignal();  
    worker.join();  
    return 0;  
}

ready 是一个普通的 bool 变量,不是原子的。因此,在多线程环境中对它的读写可能会导致数据竞争和不确定的行为。

<2>.std::atomic例子:线程间的信号通知

#include <iostream>  
#include <thread>  
#include <atomic>  
#include <chrono>  
  
std::atomic<bool> ready(false); // 初始化为 false 的原子布尔变量  
  
void workerThread() {  
    std::this_thread::sleep_for(std::chrono::seconds(1)); 
    ready.store(true); // 设置 ready 为 true,通知其他线程  
    std::cout << "Worker thread finished its work.\n";  
}  
  
int main() {  
    std::thread t(workerThread);  
  
    while (!ready.load()) {  
        std::cout << "Waiting for the worker thread to finish...\n";  
        std::this_thread::sleep_for(std::chrono::milliseconds(100)); // 等待 worker 线程完成  
    }  
  
    std::cout << "Main thread detected that the work is ready.\n";  
    t.join();  
    return 0;  
}

工作线程运行一个循环,直到 running 变量被设置为 false。主线程在一段时间后设置 running 为 false,工作线程检测到这个变化后停止循环。由于 running 是原子的,因此这个检查操作是线程安全的。

相关推荐

  1. C++ bool 布尔类型

    2024-03-30 00:46:03       59 阅读
  2. boolBOOL区别

    2024-03-30 00:46:03       48 阅读
  3. Spring Boot:()常用参数注解使用

    2024-03-30 00:46:03       28 阅读
  4. 第二

    2024-03-30 00:46:03       59 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-03-30 00:46:03       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-03-30 00:46:03       106 阅读
  3. 在Django里面运行非项目文件

    2024-03-30 00:46:03       87 阅读
  4. Python语言-面向对象

    2024-03-30 00:46:03       96 阅读

热门阅读

  1. js移除子元素

    2024-03-30 00:46:03       38 阅读
  2. 应用Druid解析SQL获取查询表字段、参数信息

    2024-03-30 00:46:03       37 阅读
  3. 5.89 BCC工具之tcptop.py解读

    2024-03-30 00:46:03       34 阅读
  4. PTA 道路管制

    2024-03-30 00:46:03       40 阅读
  5. VUE3从i18n国际化组件动态获取字符串

    2024-03-30 00:46:03       39 阅读
  6. 星图金融价值跃迁:打造“一体两翼”正向循环

    2024-03-30 00:46:03       43 阅读
  7. 5、Cocos Creator 动作系统

    2024-03-30 00:46:03       40 阅读
  8. Composer常见错误以及常用解决办法指南

    2024-03-30 00:46:03       39 阅读
  9. Vue模板引用(ref),超详细

    2024-03-30 00:46:03       44 阅读
  10. Asp.net Core 中一键注入接口

    2024-03-30 00:46:03       41 阅读