C++中std::atomic_bool详解和实战示例

std::atomic_bool 是 C++ 标准库中提供的一种 原子类型,用于在多线程环境下对布尔值进行 线程安全的读写操作,避免使用 std::mutex 带来的性能开销。


1. 基本作用

在多线程环境中,多个线程同时访问一个 bool 类型变量可能会出现 竞态条件(race condition)。使用 std::atomic_bool 可以确保:

  • 每次读取和写入都是 原子性的
  • 不需要手动加锁;
  • 性能比 std::mutex 更好,适用于控制标志位等简单变量。

2. 常用操作

操作说明
load()原子读取值
store(true/false)原子写入值
exchange(value)原子地将值替换为 value 并返回旧值
compare_exchange_weak原子比较并条件赋值(弱)
compare_exchange_strong原子比较并条件赋值(强)

3. 示例代码:线程安全的停止标志

#include <iostream>
#include <thread>
#include <atomic>
#include <chrono>std::atomic_bool stop_flag(false);void worker_thread() {std::cout << "Worker thread started.\n";while (!stop_flag.load()) {std::this_thread::sleep_for(std::chrono::milliseconds(500));std::cout << "Working...\n";}std::cout << "Worker thread stopping.\n";
}int main() {std::thread t(worker_thread);std::this_thread::sleep_for(std::chrono::seconds(2));std::cout << "Main thread: stopping worker.\n";stop_flag.store(true); // 原子写入,通知线程退出t.join();std::cout << "Main thread: done.\n";return 0;
}

4. exchange() 用法示例

std::atomic_bool flag(false);// 原子地将 flag 设置为 true,并获取旧值
bool was_set = flag.exchange(true);
if (!was_set) {std::cout << "First time setting flag!\n";
} else {std::cout << "Flag was already set.\n";
}

5. compare_exchange_strong() 用法示例

std::atomic_bool ready(false);
bool expected = false;if (ready.compare_exchange_strong(expected, true)) {std::cout << "We changed it from false to true.\n";
} else {std::cout << "It was already true.\n";
}

compare_exchange_strong(expected, new_val) 的意思是:

  • 如果当前值 == expected,则原子地赋值为 new_val,并返回 true
  • 否则返回 false,且 expected 被更新为当前值。

6. 和 volatile 的区别?

项目std::atomicvolatile
原子性保证
线程安全
用于多线程❌(不适用)

7. 典型应用场景

  • 线程停止标志(如 kill_switch, terminate_flag
  • 单次初始化控制(once_flag 替代方案)
  • 简单信号通信(如触发事件)

8. 实战应用示例

在建图(SLAM)系统中,std::atomic_bool 通常用于 线程控制标志,以线程安全方式实现异步逻辑的终止、控制或状态指示。以下是详细用途、使用示例,以及与建图模块结合的典型场景。


建图系统中常见使用场景

变量名类型作用说明
kill_switchstd::atomic_bool强制立即终止后端建图线程
end_of_sequencestd::atomic_bool等待数据队列处理完后自动终止线程
request_to_optimizestd::atomic_bool请求触发一次后端优化
request_to_recoverstd::atomic_bool请求重新恢复全局状态或轨迹
is_mappingstd::atomic_bool指示建图线程当前是否运行中
has_new_datastd::atomic_bool用于触发新数据到来时的条件变量唤醒

建图线程中的使用示例

class AsyncMapping {
public:AsyncMapping() : kill_switch(false), end_of_sequence(false), request_to_optimize(false) {mapping_thread = std::thread(&AsyncMapping::run, this);}~AsyncMapping() {kill_switch.store(true);         // 强制中断condition.notify_all();if (mapping_thread.joinable()) mapping_thread.join();}void insert_submap(const SubMap::Ptr& submap) {{std::lock_guard<std::mutex> lock(queue_mutex);submap_queue.push(submap);}request_to_optimize.store(true);condition.notify_one(); // 唤醒线程}private:void run() {while (!kill_switch.load()) {std::unique_lock<std::mutex> lock(queue_mutex);condition.wait(lock, [&]() {return kill_switch.load() || !submap_queue.empty() || request_to_optimize.load();});if (kill_switch.load()) break;// 处理队列while (!submap_queue.empty()) {auto submap = submap_queue.front();submap_queue.pop();process_submap(submap);}if (request_to_optimize.exchange(false)) {optimize(); // 执行一次后端优化}}}void process_submap(const SubMap::Ptr& submap);void optimize();private:std::atomic_bool kill_switch;std::atomic_bool end_of_sequence;std::atomic_bool request_to_optimize;std::queue<SubMap::Ptr> submap_queue;std::mutex queue_mutex;std::condition_variable condition;std::thread mapping_thread;
};

** 技巧说明**

  • atomic_bool + condition_variable 是建图线程中典型的等待-通知机制组合。
  • exchange(false) 常用于“消费型”标志,即只触发一次(如 request_to_optimize)。
  • 在析构时使用 kill_switch 可以 无锁安全终止线程,无需强行 detach

推荐命名规范

标志变量推荐用途
kill_switch强制立即终止所有建图处理
optimization_flag表示优化请求
data_ready数据队列中是否有数据可处理
map_updated是否生成新地图输出
need_save是否需要保存地图(外部触发)

如果使用 ThreadPool + std::future,也可以这样结合:

if (request_to_optimize.exchange(false)) {thread_pool.submit([this]() {global_mapping->optimize();  // 异步触发建图优化});
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/89386.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/89386.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

深度学习之分类手写数字的网络

面临的问题 定义神经⽹络后&#xff0c;我们回到⼿写识别上来。我们可以把识别⼿写数字问题分成两个⼦问题&#xff1a; 把包含许多数字的图像分成⼀系列单独的图像&#xff0c;每个包含单个数字&#xff1b; 也就是把图像 &#xff0c;分成6个单独的图像 分类单独的数字 我们将…

nginx基本使用 linux(mac下的)

目录结构 编译后会有&#xff1a;conf html logs sbin 四个文件 &#xff08;其他两个是之前下载的安装包&#xff09; conf&#xff1a;配置文件html&#xff1a;页面资源logs&#xff1a;日志sbin&#xff1a;启动文件&#xff0c;nginx主程序 运行后多了文件&#xff1a;&l…

基于大众点评的重庆火锅在线评论数据挖掘分析(情感分析、主题分析、EDA探索性数据分析)

文章目录 有需要本项目的代码或文档以及全部资源&#xff0c;或者部署调试可以私信博主项目介绍数据采集数据预处理EDA探索性数据分析关键词提取算法情感分析LDA主题分析总结每文一语 有需要本项目的代码或文档以及全部资源&#xff0c;或者部署调试可以私信博主 项目介绍 本…

鸿蒙系统(HarmonyOS)应用开发之经典蓝色风格登录页布局、图文验证码

一、项目概述 本项目是一款基于鸿蒙 ArkTS&#xff08;ETS&#xff09;开发的用户登录页面&#xff0c;集成了图文验证码功能&#xff0c;旨在为应用提供安全、便捷的用户身份验证入口。项目采用现代化 UI 设计&#xff0c;兼顾用户体验与安全性&#xff0c;适用于多种需要用户…

0.96寸OLED显示屏 江协科技学习笔记(36个知识点)

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 32 33 34 35 36

Flutter SnackBar 控件详细介绍

文章目录 Flutter SnackBar 控件详细介绍基本特性基本用法1. 显示简单 SnackBar2. 自定义持续时间 主要属性高级用法1. 带操作的 SnackBar2. 自定义样式3. 浮动式 SnackBar SnackBarAction 属性实际应用场景注意事项完整示例建议 Flutter SnackBar 控件详细介绍 SnackBar 是 F…

【C++】头文件的能力与禁忌

在C中&#xff0c;​头文件&#xff08;.h/.hpp&#xff09;​​ 的主要作用是声明接口和共享代码&#xff0c;但如果不规范使用&#xff0c;会导致编译或链接错误。以下是详细总结&#xff1a; 一、头文件中可以做的事情 1.1 声明 函数声明&#xff08;无需inline&#xff…

腾讯 iOA 零信任产品:安全远程访问的革新者

在当今数字化时代&#xff0c;企业面临着前所未有的挑战与机遇。随着远程办公、多分支运营以及云计算的广泛应用&#xff0c;传统的网络安全架构逐渐暴露出诸多不足。腾讯 iOA 零信任产品凭借其创新的安全理念和强大的功能特性&#xff0c;为企业提供了一种全新的解决方案&…

IP5219全集成Type-C移动电源SOC!2.1A快充+2.4A放电,极简BOM方案

产品概述&#xff1a; IP5219是一款集成升压转换器、锂电池充电管 理、电池电量指示和TYPE_C协议的多功能电源管 理SOC&#xff0c;为移动电源提供完整的电源解决方案。 IP5219的高集成度与丰富功能&#xff0c;使其在应用时 仅需极少的外围器件&#xff0c;并有效减小整体方案…

报道称CoreWeave洽谈收购Core Scientific,后者涨超30%

CoreWeave与数字基础设施公司Core Scientific的收购事宜可能在未来几周内敲定交易&#xff0c;前提是双方不出现重大分歧。消息传出后&#xff0c;Core Scientific股价一度暂停交易&#xff0c;随后恢复交易最终收涨逾32%。 AI云服务巨头CoreWeave正与数字基础设施公司Core Sc…

Qt5.15.2实现WebAssembly:2、设置emsdk目录

步骤1 打开QT&#xff0c;编辑&#xff0c;Preference&#xff08;首选项&#xff09;&#xff1a; 设备&#xff0c;WebAssembly&#xff0c;游览。 找到安装好的emscripten目录&#xff0c;选择。 稍等一会&#xff0c;QT会解析出相应的信息&#xff0c;再点确定。 图中…

SpringMVC--使用RESTFul实现用户管理系统

一、静态页面准备 1. user.css .header {background-color: #f2f2f2;padding: 20px;text-align: center; }ul {list-style-type: none;margin: 0;padding: 0;overflow: hidden;background-color: #333; }li {float: left; }li a {display: block;color: white;text-align: ce…

hello算法_C++_ 最差、最佳、平均时间复杂度

算法的时间效率往往不是固定的&#xff0c;而是与输入数据的分布有关。假设输入一个长度为 的数组 nums &#xff0c;其中 nums 由从 1 至 n 的数字组成&#xff0c;每个数字只出现一次&#xff1b;但元素顺序是随机打乱的&#xff0c;任务目标是返回元素 的索引。我们可以…

2024考研数一真题及答案

历年数一真题及答案下载直通车 已知函数 f ( x ) ∫ 0 x e cos ⁡ t d t f(x) \int_0^x e^{\cos t} dt f(x)∫0x​ecostdt&#xff0c; g ( x ) ∫ 0 sin ⁡ x e t 2 d t g(x) \int_0^{\sin x} e^{t^2} dt g(x)∫0sinx​et2dt&#xff0c;则&#xff08; &#xff09;。 A…

MIT 6.824学习心得(2) 浅谈多线程和RPC

上篇文章中我们简单介绍了分布式系统的设计思想以及简单性质&#xff0c;之后用一定篇幅简要介绍了MapReduce这个经典的分布式计算框架的大致工作原理&#xff0c;相信朋友们已经对此有了最基本的理解。在现实场景中&#xff0c;分布式系统的设计初衷是为了解决并发问题&#x…

opensuse/debian grub启动界面太模糊?

现代操作系统或者新电脑使用那么模糊的界面启动&#xff0c;虽然没有什么不良反应&#xff0c;但是多少有点看不过去&#xff0c;这是因为为了保证正常启动做出的适配。而我们可以对其分辨率进行选定。 1 您好&#xff0c;非常感谢您提供的截图。这张图片非常关键&#xff0c…

zookeeper Curator(5):集群架构和集群搭建

文章目录 一、集群架构&#xff1a;Leader-Follower 模式二、核心机制&#xff1a;ZAB 协议三、Leader 选举机制四、集群部署要点五、优势与挑战 Zookeeper 集群是一个由多个 Zookeeper 服务实例组成的分布式协调服务系统&#xff0c; 通过奇数个节点&#xff08;通常 3、5、7…

道可云人工智能每日资讯|浦东启动人工智能创新应用竞赛

道可云人工智能&元宇宙每日简报&#xff08;2025年7月1日&#xff09;讯&#xff0c;今日人工智能&元宇宙新鲜事有&#xff1a; 江城模境工信部人工智能大模型公共服务平台&#xff08;武汉&#xff09;上线运行 2025年6月27日&#xff0c;光谷人工智能创新大会在湖北…

Python元组的遍历

一、前言 在 Python 中&#xff0c;元组&#xff08;tuple&#xff09; 是一种非常基础且常用的数据结构&#xff0c;它与列表类似&#xff0c;都是有序的序列&#xff0c;但不同的是&#xff0c;元组是不可变的&#xff08;immutable&#xff09;&#xff0c;一旦创建就不能修…

矩阵的条件数(Condition Number of a Matrix)

文章目录 矩阵的条件数&#xff08;Condition Number of a Matrix&#xff09;&#x1f4cc; 定义&#x1f9ee; 常见形式&#xff1a;2-范数下的条件数&#x1f50d; 条件数的意义&#x1f9e0; 实际意义举例&#x1f4bb; Python 示例&#xff08;NumPy&#xff09;&#x1f…