当前位置: 首页 > news >正文

同步与互斥学习笔记

一、基本概念

同步与互斥是多任务/多线程编程中的两个核心机制:

  • 同步:指多个任务之间存在明确的先后顺序,一个任务必须等待另一个任务完成某些操作后才能继续执行。

  • 互斥:指多个任务在同一时刻争抢使用同一资源(临界资源),必须通过某种机制保证同一时间只有一个任务可以使用该资源。


二、线程安全问题的由来

问题描述

当多个任务同时访问一个共享资源(如全局变量)时,如果没有适当的保护机制,就会出现数据不一致的问题。

示例分析:全局变量 count++

c

int count = 0;
// 两个线程同时执行 count++

count++ 实际上包含三个步骤(非原子操作):

  1. 读取 count 的值到寄存器

  2. 对寄存器中的值加 1

  3. 将结果写回 count 的内存地址

执行流程(可能出现的问题):

  1. 线程 A 读取 count = 0,准备加 1;

  2. 此时切换到线程 B,也读取 count = 0,完成加 1 并写回,count 变为 1;

  3. 切换回线程 A,继续执行加 1(基于之前读到的 0),写回后 count 仍为 1。

预期结果为 2,实际结果为 1,这就是典型的线程安全问题,也称为数据竞争


三、同步机制的缺陷

  • 使用同步机制(如忙等待)会导致任务死等,浪费 CPU 资源。

  • 应避免使用 while() 循环进行无意义的等待,而应使用阻塞机制让出 CPU。


四、全局变量在 RTOS 中的存储位置

问题:全局变量存储在哪个栈中?

答案:全局变量不属于任何一个任务的栈。

内存区域划分:

  1. 代码区 (Text Segment):存放程序指令。

  2. 全局/静态数据区 (Data/BSS Segment)

    • 存放全局变量静态变量

    • 在程序启动时分配,生命周期贯穿整个程序;

    • 被所有任务和中断共享。

  3. 堆区 (Heap):动态分配的内存(如 malloc / pvPortMalloc)。

  4. 栈区 (Stack)

    • 主栈/中断栈:用于 ISR 和内核调度;

    • 任务栈:每个任务独立拥有,用于存放局部变量和上下文。

结论:

全局变量存储在全局数据区,是共享资源,访问时需使用临界区、信号量、互斥锁等机制进行保护。


五、volatile 关键字的作用

问题背景:

在编译器优化的情况下,可能会将变量缓存在寄存器中,导致多任务环境中读取到旧值

示例代码(无 volatile):

c

int g_calc_end = 0;// Writer 任务
void vWriterTask(void *pvParameters) {while(1) {g_calc_end = 1; // 修改全局变量}
}// Reader 任务
void vReaderTask(void *pvParameters) {while(1) {if (g_calc_end == 1) { // 判断全局变量// 执行操作g_calc_end = 0;}vTaskDelay(1);}
}

问题流程:

  1. Reader 任务第一次读取 g_calc_end 到寄存器;

  2. 编译器优化后,后续判断直接使用寄存器中的值(不再从内存读取);

  3. Writer 任务修改了内存中的 g_calc_end

  4. Reader 任务仍然使用寄存器中的旧值,导致判断错误。

解决方案:使用 volatile

c

volatile int g_calc_end = 0;

volatile 的作用:

  • 告诉编译器该变量是“易变的”;

  • 禁止对其进行优化:

    • 每次读取必须从内存中重新加载;

    • 每次写入必须立即写回内存。


六、补充与总结

疏漏补充:

  1. 原子操作:某些架构提供原子指令(如 __atomic_inc),可避免数据竞争;

  2. 临界区保护:使用开关中断、调度器锁、互斥量等方法保护共享资源;

  3. 任务通信机制:除了全局变量,还可使用队列、事件组、信号量等进行任务间同步与通信;

  4. 内存屏障:在多核系统中,可能需要使用内存屏障指令确保内存访问顺序。

总结图示:

(见原笔记中的图片,图示展示了同步与互斥的机制和资源访问流程)


七、最佳实践建议

  1. 尽量避免使用全局变量,优先使用 RTOS 提供的通信机制;

  2. 若必须使用共享资源,务必使用互斥锁或信号量进行保护;

  3. 对于可能被异步修改的变量,必须使用 volatile 声明;

  4. 在临界区中尽量减少操作时间,避免影响系统实时性;

  5. 合理使用任务阻塞机制,避免忙等待浪费 CPU 资源。


文章转载自:

http://Wm7gmNFT.qfqLd.cn
http://3zVR741U.qfqLd.cn
http://eU3Zsgwc.qfqLd.cn
http://0zMjL88E.qfqLd.cn
http://vtWRrqLY.qfqLd.cn
http://lZyI3a8K.qfqLd.cn
http://q1AHHkmD.qfqLd.cn
http://7ebNopDA.qfqLd.cn
http://dC52ADc4.qfqLd.cn
http://YLBT4oMd.qfqLd.cn
http://a1XsJT8W.qfqLd.cn
http://GEDkmomW.qfqLd.cn
http://ggODJmQw.qfqLd.cn
http://7S14Q7Om.qfqLd.cn
http://kHBga7mi.qfqLd.cn
http://du74TuFl.qfqLd.cn
http://SBIlmA3M.qfqLd.cn
http://WuPOYc9c.qfqLd.cn
http://btJ9LlV5.qfqLd.cn
http://1bcKRZIu.qfqLd.cn
http://dDriPQkl.qfqLd.cn
http://m39D9xxl.qfqLd.cn
http://f5IWbYVU.qfqLd.cn
http://3ZN63vTK.qfqLd.cn
http://0VxMD8nu.qfqLd.cn
http://3LMASUTj.qfqLd.cn
http://HCl2TN1g.qfqLd.cn
http://2ZLozFce.qfqLd.cn
http://sPzSEnEB.qfqLd.cn
http://WhVIRIlo.qfqLd.cn
http://www.dtcms.com/a/387943.html

相关文章:

  • 命令行方式部署OceanBase 集群部署
  • 小迪安全v2023学习笔记(八十四讲)——协议安全桌面应用hydra爆破未授权检测
  • MAC-简化版枚举工具类
  • Science Robotics 美国康奈尔大学开发的新型触觉显示器
  • Java 零基础学习指南
  • 音频剪辑总出错?音视频分割工具免费功能实测 音视频分割工具新手怎么用?4步搞定音视频分割 音视频分割工具常见问题解决:新手避坑参考
  • 线性回归与 Softmax 回归总结
  • 文字一键生成视频软件哪家比较靠谱?
  • Android,Jetpack Compose,坦克大战游戏案例Demo(随机生成地图)
  • Unity 笔记:构建AAB包大小超过谷歌商店上限
  • 在idea中git修改用户名和邮箱/切换账号
  • 设计模式(C++)详解——组合模式(Composite Pattern)(1)
  • 103、23种设计模式之外观模式(12/23)
  • 依赖注入基础
  • 代码随想录二刷之“图论”~GO
  • 基础数学转金融数学考研:一场需要清醒规划的转型
  • Alpha World携手非小号Talking Web3,海上ALPHA WEB3派对启航
  • Vue3钩子,路由拦截实现
  • 数据结构七大排序算法模拟实现性能分析
  • vue+react笔记
  • springboot获取wav文件音频长度
  • 【Redis】-- 缓存
  • 鸿蒙高效数据处理框架全攻略:缓存、并行与流式实战
  • 全网首发! Nvidia Jetson Thor 128GB DK 刷机与测评(五)常用功能测评 - RealtimeSTT 音频转文本 同声传译
  • OpenHarmony 之生态规则管控服务(Ecological Rule Manager Service)源码深度解读
  • 无人机图传是什么意思 应用和趋势是什么?
  • arm coresight
  • Vue3 + vue-draggable-plus 实现可拖拽的数据源选择面板
  • Vue 项目主题切换功能实现:两种方案详解与选型分析
  • 有些软件要求基础环境包含oneAPI组件时带有小版本怎么解释