C++ 多线程:条件变量防虚假唤醒与 atomic 急停信号

C++ 多线程:条件变量防虚假唤醒与 atomic 急停信号

一、背景

机器人控制回路里,线程同步主要就两类问题:

  • 等事件:等传感器数据、等规划结果、等上位机指令。
  • 发信号:急停、看门狗超时、安全区域越界。

条件变量解决前者,atomic 解决后者。下面按 SOP 整理。

二、SOP 实操

步骤 操作 说明
1 保存为 exercise7.cpp 文件名与代码一致
2 g++ -std=c++17 -pthread exercise7.cpp -o exercise7 编译
3 ./exercise7 运行
4 观察输出 先跑生产者-消费者,再跑急停
5 验证结果 消费者收到 42;运动被急停打断

三、架构

程序分两块:

  1. 条件变量同步 :producer 写数据并置 ready = true,consumer 通过 cv.wait 带谓词等待,防止虚假唤醒。
  2. atomic 跨线程信号 :main 线程写 emergencyStop,safetyMonitor 和 motionController 只读,实现无锁急停。

四、重难点解决方案

问题 原因 解法
虚假唤醒 线程可能未 notify 就被唤醒 cv.wait 必须带谓词,或用 while 循环
if 判断 ready 不可靠 唤醒后不再检查,队列可能为空 改成 cv.wait(lk, []{ return ready; })
notify 放在锁内 被唤醒线程可能立刻阻塞在锁上 notify_one 放在锁外
急停信号跨线程不可见 普通 bool 不保证可见性 用 std::atomic<bool>
急停用 relaxed 是否安全 relaxed 只保证原子性 单一标志位、无其他变量顺序依赖时可用
多变量有顺序依赖 relaxed 不保证先后顺序 升级为 acquire-release,或回到 mutex

五、预期输出

复制代码
=== 条件变量生产者-消费者 ===
生产者:已发送数据并通知
消费者:收到数据 42

=== atomic急停信号 ===
[运动控制] 执行第 1 步
[运动控制] 执行第 2 步
[运动控制] 收到急停,停止运动
[安全监控] 检测到急停信号!立即切断电机!

步数取决于调度顺序,但急停一定会触发。

六、工程要点

  • 条件变量:wait 永远带谓词,别用 if;notify 尽量放锁外。
  • atomic 急停:单一标志位用 relaxed 性能最优;多变量有顺序依赖时升级为 acquire-release。
  • 机器人场景:急停按钮、看门狗、安全越界都用 atomic 广播,比 mutex 轻,不阻塞控制回路。
相关推荐
普通人614 小时前
WebGL与WebGPU入门指南
开发语言·webgl·1024程序员节
猫猫不是喵喵.1 天前
从0到1创建一个微服务项目
java·数据库·微服务·1024程序员节
fish_zzzz5 天前
笔记-论数据结构2
1024程序员节
普通人65 天前
PHP文件读写完全指南
开发语言·php·1024程序员节
Martina_03215 天前
AI生成3D场景从白模换成精模后镜头全偏了?用6步检查单位、枢轴与层级替换
图像处理·人工智能·3d·ai·自然语言处理·材质·1024程序员节
星云_byto7 天前
CSS布局
人工智能·机器学习·目标跟踪·1024程序员节
张小姐的猫9 天前
【MySQL】访问 & 数据流动原理
android·数据库·mysql·adb·1024程序员节
工业HMI实战笔记10 天前
印刷电路板HMI:SMT贴装的元件定位界面
制造·设计规范·设计语言·1024程序员节
Martina_032110 天前
AI生成3D模型一合并网格,材质就串色?用6步检查材质槽、UV与图集重映射
图像处理·人工智能·3d·材质·uv·游戏策划·1024程序员节
橙光成长10 天前
android-ad-cleaner:android免 Root 批量关闭系统开屏与营销推送
android·1024程序员节