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 轻,不阻塞控制回路。
相关推荐
临床数据科学和人工智能兴趣组1 小时前
提取匹配模式的第一个值
人工智能·r语言·1024程序员节·r语言-4.2.1·临床试验·临床科研·科学问题
MasonYyp1 小时前
‌WSL简单使用
1024程序员节
todoitbo1 小时前
Q1 MuJoCo 模型里的 49 项传感器定义与 60 维数据:一次关节和 IMU 输出核验
人工智能·ai·机器人·1024程序员节·启元机器人
小嘉丶学长1 小时前
Day03 · 虚拟环境与依赖管理入门
1024程序员节
墨抒颖 msy.plus2 小时前
矩阵、注意力与 GPU:拆解 DeepGEMM 与 FlashMLA
人工智能·llm·gpu·源码解析·1024程序员节·deepseek
小冷coding2 小时前
Codex 下载与本地部署实战:从环境准备到跑通第一个任务
1024程序员节
郝学胜-神的一滴2 小时前
游戏设计:原型与开发 11:用概率与电子表格搞定骰子系统
程序人生·游戏·游戏策划·1024程序员节·游戏设计
lusklusklusk2 小时前
Python 流程控制与异常处理笔记:break、continue、pass、return 与 try-except-finally
1024程序员节