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

【操作系统】共享数据的竞争问题

共享数据的竞争问题

  • 问题:保护中断与主程序共享的avg_data
    • 方法一:使用关中断保护
      • 1. 添加关中断宏
      • 2. 修改数据读取代码
      • 3. 修改中断服务程序(ISR)
    • 方法二:使用原子操作(需平台支持)
      • 1. 定义原子类型
      • 2. 修改数据访问代码
    • 方法三:使用RTOS同步机制(如信号量)
      • 1. 扩展通道结构体
      • 2. 初始化信号量
      • 3. 保护数据访问
  • 方案对比与选型建议
  • 关键验证点

问题:保护中断与主程序共享的avg_data

在嵌入式系统中,中断服务程序(ISR)和主程序(或任务)共享数据时,必须确保访问的原子性可见性。以下是针对该问题的具体修改步骤:

方法一:使用关中断保护

此方法通过临时禁用中断来确保对共享变量的原子访问,适用于所有平台。

1. 添加关中断宏

在头文件中定义关中断宏:

2. 修改数据读取代码

hal_get_data 函数中保护 avg_data 的读取:

int hal_get_data() {
    ENTER_CRITICAL();   // 进入临界区(关中断)
    *val = avg_data;   // 安全读取共享数据
    EXIT_CRITICAL();    // 退出临界区(开中断)

    return 0;
}

3. 修改中断服务程序(ISR)

module_isr 中保护 avg_data 的写入:

irqreturn_t module_isr() {
        ENTER_CRITICAL();
        avg_data = 8888;// 安全更新 avg_data
        EXIT_CRITICAL();
        sem_give(complete);
    }
    // ...
}

注意这个做法是有风险的,在中断处理函数中关中断需谨慎,可能破坏中断上下文的状态或影响实时性详细分析见博客

方法二:使用原子操作(需平台支持)

如果目标平台支持对 u16 类型的原子访问(如ARM Cortex-M),可使用原子操作。

1. 定义原子类型

在结构体中声明 avg_data 为原子变量:

#include <stdatomic.h>

struct siliumixi {
    // ...
    _Atomic u16 avg_data; // C11原子类型
    // ...
};

2. 修改数据访问代码

  • ISR中原子写入

    atomic_store(&chan->avg_data, calculated_value);
    
  • 主程序原子读取

        *val = atomic_load(&chan->avg_data); // 原子读取
    

方法三:使用RTOS同步机制(如信号量)

在RTOS环境中,可通过信号量确保数据访问的同步。

1. 扩展通道结构体

struct siliumixi {
    // ...
    sem_t data_sem; // 新增信号量
    // ...
};

2. 初始化信号量

在初始化时创建信号量:

    chan->data_sem = sem_create(1); // 初始值为1(二进制信号量)
}

3. 保护数据访问

  • ISR中释放信号量

    
            sem_take(chan->data_sem, 0);    // 获取信号量(非阻塞)
            chan->avg_data = 8888;      // 更新数据
            aicos_sem_give(chan->data_sem);       // 释放信号量
        }
        // ...
    }
    
  • 主程序获取信号量

        if (sem_take(chan->data_sem, timeout) != 0)
            return -ETIMEDOUT;
        *val = chan->avg_data;
    
    }
    

方案对比与选型建议

方案优点缺点适用场景
关中断简单高效,无额外资源消耗影响中断响应实时性低延迟、单核嵌入式系统
原子操作代码简洁,无锁竞争依赖平台原子操作支持支持C11原子类型的平台
RTOS信号量兼容多任务环境,灵活增加RTOS开销,需处理信号量超时基于RTOS的多任务系统

关键验证点

  1. 原子性测试:在高低优先级任务/中断同时访问时,数据是否一致。
  2. 性能测试:关中断时长是否影响其他中断响应(使用示波器测量最坏关中断时间)。
  3. 资源占用:信号量或原子操作是否增加内存/CPU开销。

通过上述任一方法,可有效解决共享数据 chan->avg_data 的竞争问题

相关文章:

  • Python预训练模型实现俄语音频转文字
  • 2025年渗透测试面试题总结- 某亭-安全研究员(题目+回答)
  • Redis设计与实现-底层实现
  • 视频录制与输出指南:获得最佳效果的关键参数
  • 数据结构---图的深度优先遍历(DFS)
  • LangChain其它五类组件详解(1)—— 文档加载器(Document loaders)
  • FRP结合Nginx实现HTTPS服务穿透
  • JVM 知识点梳理
  • 【前四届会议均已完成独立出版及EI检索 | 河南大学、河南省科学院主办,多高校单位承协办】第五届信号图像处理与通信国际学术会议(ICSIPC 2025)
  • Vue 中的日期格式化实践:从原生 Date 到可视化展示!!!
  • 如何在 HTML 中创建一个有序列表和无序列表,它们的语义有何不同?
  • SpringBoot最佳实践之 - 使用AOP记录操作日志
  • 第五章 起航19 管理者的专业素养
  • 下载与快速上手 NVM:Node.js 版本管理工具
  • 机器学习——分类、回归、聚类、LASSO回归、Ridge回归(自用)
  • 深入理解 Spring Boot 应用的生命周期:从启动到关闭的全流程解析
  • 【开源项目】数字孪生沈阳CIM/BIM可视化项目——开源工程及源码
  • 1202. 【高精度练习】义务植树
  • java 数据库连接基于向驱动管理器注册第三方驱动的机制介绍,包含三种注册类型和华为高斯(GaussDB)数据库的完整连接例子
  • 算法模型从入门到起飞系列——背包问题(探索最大价值的掘金之旅)
  • 西北大学副校长成陕西首富?旗下巨子生物去年净利超20亿,到底持股多少
  • 沙县小吃中东首店在沙特首都利雅得开业,首天营业额超5万元
  • 新剧|《藏海传》定档,《折腰》《人生若如初见》今日开播
  • 重庆一高校75万采购市价299元产品?工作人员:正在处理
  • 伊朗外长称正与美国进行“善意”的会谈
  • 2025上海十大动漫IP评选活动启动