Linux驱动学习——并发和竞态

短信验证码逻辑漏洞学习——各种绕过姿势技巧 阅读详情

linux内核并发和竞态:

并发:多个执行单元同时发生(进程和中断)

竞态:多个执行单元对共享资源的访问。

          条件:

          1.并发

          2.共享资源

          3.同时访问

共享资源:硬件资源和软件上的全局变量。硬件资源大到一个串口设备,小到寄存器的某个bit位

互斥访问:当一个执行单元在访问共享资源时,其他执行单元禁止访问。

临界区:访问和操作共享数据的代码区域。

 

产生竞态的情况:

1.对称多处理器(SMP),因为多个CPU之间共享内存,外存,系统的IO等,必然成竞态

2.单CPU的内核支持进程的抢占,高优先级的进程能够抢占的优先级进程的CPU资源。如果这两个进程对共享资源访问,会形成竞态

3.中断和进程,硬件中断的优先级高于软中断,软中断高于进程!

4.中断和中断

(这些情况设计的任务必须同时要访问共享资源!否则不会形参竞态)

 

linux内核提供解决竞态,实现同步访问的机制:

中断屏蔽

原子操作

自旋锁

信号量

 

1.中断屏蔽

  解决的竞态问题:进程之间的抢占,进程和中断,中断和中断。

  CPU具备屏蔽中断和打开中断的功能:可以操作CPSR或者中断控制器。

   使用:

   unsigne long flags;

         local_irq_disable();//关中断

    临界区

    local_irq_enable(); //使能中断

   或者

         local_irq_save(flags); //关中断保存状态

         临界区

         local_irq_restore(flags); //使能中断恢复状态

 

使用注意事项:长时间的屏蔽中断,会导致操作系统系统很多跟中断相关的功能无法得到正常的运行,比如进程的调度,定时器的,时间的更新等,都无法进行,这种情况会造成数据的丢失,甚至是系统的崩溃。所以在使用中断屏蔽这个互斥机制时,一定要求临界区的代码执行速度越快越好。

 

2.原子操作

  原子操作的实现严重依赖CPU的架构!

原子操作分为:

1)位原子操作:

  位操作:例如

       intg_data = 0x55; //共享资源

                  led_open(...) {

               data = g_data & 0x 1; //位操作

        }//这种位操作具备原子性

如果要对共享资源进行位操作,并且考虑竞态问题,这时推荐使用内核提供的位原子操作,就是利用内核提供的位操作方法来对共享资源进行位操作。这些方法保证对共享资源的位操作是原子的。

set_bit/clear_bit/change_bit/test_bit 组合函数

头文件#include <asm/bitops.h>

 

内核set_bit等函数的实现依赖ARM的两条特殊指定:ldrex,strex,这两条指令是原子的加载和存储指令。CPU在执行这个指令,保证在CPU硬件上是原子的。比如一个CPU在执行这个代码时,另一个CPU就会在忙等待。如果使用这两条指令,虽然保证互斥,但是代码的执行效率上会降低。

 

2)整型原子操作:

涉及的数据类型:atomic_t

如果以后在驱动程序中,使用的共享资源是一个整型数,并且是一个共享资源,如果要对这个数进行相关的运算,可以考虑使用内核提供的整型原子操作的方法,保证原子性。

切记:一下代码不具备原子性

if (--open_cnt != 0) ...//不具备原子性

 

使用:

1.分配一个原子整型变量

  atomic_t v = ATOMIC_INIT(1); //intopen_cnt = 1;

2.利用内核提供的整型原子操作的方法对变量进行运算

  atomic_set/atomic_read/atomic_add/atomic_inc...

这些函数内部的实现还是使用ldrex,strex这两条原子加载和存储指令,保证整型原子变量的访问具备原子性!

 

3.自旋锁

  数据类型:spinlock_t

特点:光有自旋锁是没有太大意义的,必须要与共享资源同时存在。如果没有获取自旋锁,其他的任务将会一直原地打转。直到持有自旋锁者释放自旋锁。自旋锁不会引起休眠。

  如何使用自旋锁:

1.分配自旋锁

  spinlock_t lock

2.初始化自旋锁

  spin_lock_init(&lock);

3.如果要访问共享资源

  获取锁

  spin_lock(&lock); //如果获取锁,立即返回,否则一直忙等待

  或者

  spin_trylock(&lock);//如果获取锁,返回true,否则返回false,所以使用这个函数一定要对其返回值做判断!

4.如果获取锁,则访问共享资源

5.如果访问完毕,释放锁

  spin_unlock(&lock);

 

注意:以上涉及的自旋锁的操作方法,除了中断,其他竞态问题都能解决。如果要使用自旋锁解决中断引起的竞态,可以使用衍生自旋锁(可以解决所有的竞态问题)。

衍生自旋锁的使用:

获取锁:

unsigned long flags;

spin_lock_irq()/spin_lock_irqsave(flags);

释放锁:

spin_unlock_irq();/spin_unlock_irqrestore(flags);

 

自旋锁使用的注意事项:

自旋锁保护的临界区要求执行的速度越快越好,如果长时间的占有CPU资源,会降低系统的性能。如果使用衍生自旋锁,长时间占有CPU资源,不仅仅是性能影响,有可能还会造成数据的丢弃,甚至是操作系统的崩溃!临界区不能调用可能引起休眠的函数。

 

4.信号量

  由于自旋锁保护的临界区不能做休眠的操作,但是某些场合需要在临界区中进行休眠,需要让其他的任务进行休眠。这时自旋锁无法满足需求,可以使用信号量。

信号量能够让其他任务再没有获取信号时,进入休眠状态,也可以在临界区中进行休眠。实际上是一个睡眠锁。它和应用程序使用的信号量是一样的。

 

数据结构:

struct semaphore

 

如何使用信号量:

1.分配信号量

  struct semaphore sema;

2.初始化信号量

  sema_init(&sema, 1); //初始化为互斥信号量

3.如果要访问临界区,获取信号量

  down(&sema); //如果获取信号量,立即返回,否则进程将进入休眠状态,这种状态是不可中断的休眠状态(不会立即处理信号kill,如果醒来会判断是否接受过信号,如果有接收到信号,处理信号)

  或者

  down_interruptible(&sema);//如果获取信号量,立即返回,否则进程将进入休眠状态,这种状态是可中断的休眠状态(如果有信号kill到来,会立即处理信号),所以对这个函数一定要进行返回值的判断,如果返回0,表明正常获取信号量,如果返回非0,表明接收到了信号)

注意:以上两个函数不能在中断上下文中使用!

  或者

  down_trylock(&sema);//如果获取信号量,返回0,否则返回非0.所以这个函数也要判断判断返回值,可以在中断上下文中使用。

  

4.执行临界区

 

5.释放信号量

  up(&sema);

   一方面会释放信号量,另一方面还会唤醒休眠的进程!
AI在电商中的搜索优化 自拟标题 《AI技术助力电商搜索优化:深度解析一线大厂面试题及算法编程实践》 概述 随着人工智能技术的不断发展,AI在电商搜索优化中的应用日益广泛。本文将围绕“AI在电商中的搜索优化”这一主题,介绍国内头部一线大厂如阿里巴巴、百度、腾讯、字节跳动等在面试中常见的AI相关面试题和算法编程题,并提供详尽的答案解 阅读详情

相关推荐

SAR型ADC的电荷重分配技术解析

本文深入解析了SAR型ADC的核心技术——电荷重分配。通过类比“猜数字”游戏,阐述了其逐次逼近的工作原理,并重点剖析了电容阵列如何实现高速、低功耗的模数转换。文章还探讨了该技术在速度、能效及集成度方面的优势,并指出了电容匹配精度等实际挑战,为嵌入式与物联网设备中的ADC选型与应用提供了实用指南。

nnn11的博客 907

Linux内核的竞态和并发

什么是内核竞态,产生的原因是什么,解决内核竞态问题的方法有哪些 中断屏蔽,原子操作,自旋锁,读写锁,顺序锁,信号量,读写信号量,互斥体

qq_53221728的博客 1311

STM32H745xI双核芯片SMPS/LDO配置误区:从复位失败到精准排查的实战复盘

本文详细分析了STM32H745xI双核芯片在SMPS/LDO配置中的常见误区,特别是复位失败问题的排查过程。通过对比参考板与故障板的波形数据,揭示了电感选型不当导致的电源稳定性问题,并提供了硬件设计检查清单和调试技巧,帮助开发者避免类似陷阱。

weixin_42531588的博客 265

Linux中的进程管理

进程简述 什么是进程? 进程是已启动的可执行程序的运行实例,进程有以下组成部分: • 已分配内存的地址空间; • 安全属性,包括所有权凭据和特权; • 程序代码的一个或多个执行线程; • 进程状态。 程序: 二进制文件,静态 /bin/date, /usr/sbin/httpd,/usr/sbin/sshd, /usr/local/nginx/sbin/ngix 进程: 是程序运行的过程, 动态,...

Cuiyanbing1的博客 1963

霍尔编码器 vs 磁编码器:如何为你的电机控制项目选择最佳传感器(附实战对比)

本文深入对比了霍尔编码器和磁编码器在电机控制项目中的应用,从技术原理、性能参数、成本效益到实际场景选择提供了全面分析。通过实验室测试和项目案例,帮助工程师根据精度、环境抗性和预算选择最佳传感器方案,特别适合机器人、伺服驱动等领域的开发者参考。

weixin_28312391的博客 354

深入解析Buck开关电源中的死区时间设计及其对系统性能的影响

本文深入解析了Buck开关电源中死区时间的设计原理及其对系统性能的关键影响。死区时间通过防止上下管同时导通来避免穿通电流,确保系统安全。文章详细探讨了其工作机制、设置时的效率与安全权衡,以及不当设置对效率、稳定性和EMI的连锁反应,并提供了基于实测的调试方法与实战案例。

Apple的专栏 1132

并发竞态的解决方法

有多个进程同时访问同一个驱动程序中的临界资源的时候, 竞态就会产生了。 竞态产生的根本原因: 1.对于单核cpu,内核支持抢占。 2.多核cpu,核与核之间会产生竞态 3.中断和进程间也会产生竞态 4.中断和中断间产生竞态(中断嵌套可以)(arm架构不支持) 一、中断屏蔽(了解) 中断屏蔽只适合在单核cpu。中断屏蔽保护的临界资源 要尽可能的短(时间),如果屏蔽的时间较长,可能导致 内核的崩溃,或者用户数据的丢失。 local_irq_disable(); //临界资源 local_irq_enable()

q1449660223的博客 584

深入GD32/STM32引脚复用:你的JTAG/SWD接口是怎么‘消失’的?一次讲清原理与预防

本文深入解析GD32/STM32调试接口(JTAG/SWD)突然失效的原理与预防措施。通过分析MCU启动流程、引脚复用机制及典型错误代码模式,揭示调试接口'消失'的根本原因,并提供硬件设计检查清单、软件防护代码及开发流程优化方案,帮助开发者有效避免烧录失败问题。

weixin_42532938的博客 369

58_进程之竞态

多个进程,同时抢占系统资源,包括CPU、内存、串口设备(文件IO)等

sanbanzui2008的博客 133

手把手教你学Simulink实例--基于simulink搭建起一个基础的矩阵变换器仿真模型

矩阵变换器(Matrix Converter, MC)是一种直接将交流电源转换为另一频率和幅值的交流电源的电力电子设备,它不需要中间的直流环节。这种变换器通过控制一组双向开关来实现对输入电压的精确控制,从而产生所需的输出电压波形。Simulink提供了强大的仿真环境,可以用于设计、分析和验证基于矩阵变换器的电源系统。

MHD0815的博客 338

第10章: MMU notifier与HMM的协作

本文摘要: HMM(Heterogeneous Memory Management)是Linux内核提供的异构内存管理框架,用于统一CPU与设备(如GPU、DSP等)的内存访问。它通过镜像页表技术实现虚拟地址空间共享,自动同步CPU和设备页表变化,支持透明的内存迁移和设备内存管理。HMM构建在mmu_interval_notifier机制上,利用序列号检测页表修改冲突,提供高效并发控制。核心数据结构包括hmm_range和HMM PFN标志位,通过hmm_range_fault()实现页表遍历和缺页处理。

图形/计算GPU的驱动与虚拟化技术分享园地 3098

linux 资源竞争 引起的 阻塞 休眠 以及 驱动部分的工作

该笔记仅仅就 1)阻塞 休眠 和唤醒的基本机理

知识始于好奇,技术源于积累 1072

交通仿真软件:SUMO_(1).SUMO基础知识

SUMO 中的交通网络由节点(junctions)和边(edges)组成。节点表示交叉口或路网的连接点,边表示连接节点之间的道路。节点:节点文件(.nod.xml)定义了网络中的所有节点。每个节点有一个唯一的 ID 和坐标。</边:边文件(.edg.xml)定义了连接节点的边。每个边有一个唯一的 ID、起点节点 ID 和终点节点 ID。</车辆文件(.vtype.xml)定义了不同类型的车辆。每个车辆类型可以有不同的参数,例如长度、最大速度、加速度等。</

kkchenjj的博客 1432

linux设备驱动程序学习之并发与竞态

并发指的是多个执行单元(进程、线程、中断等)同时(并行)或交替执行(时间片轮转)的状况。竞态则是并发编程中的一种错误状态,指多个线程或进程对共享资源的访问顺序不确定,导致程序行为依赖于执行时序,可能产生不可预测的结果。并发的根源主要来自三个方面:1.对称多处理器(SMP):真正的并行,多个CPU核心可能同时执行驱动代码2.内核抢占:高优先级进程可以抢占正在内核态执行的较低优先级进程3.中断:中断处理程序可以异步打断正在执行的进程。

阿龙的工作记录 345

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

嵌入式LINUX驱动学习之8竞态和并发相关问题(零)基础理论

嵌入式LINUX驱动学习之8竞态和并发相关问题(零)基础理论一、什么是并发和竞态?二、什么是互斥访问三、互斥访问的方法:3.1 中断屏蔽3.1.1 中断屏蔽的特点:3.1.2 中断屏蔽的互斥访问过程:3.1.3 使用中断屏蔽可能带来的问题和需要注意的事项3.2 自旋锁3.2.1 自旋锁的特点:3.2.1 衍生自旋锁的特点3.3 信号量3.3.1 信号量特点:3.4 原子操作3.4.1 原子操作特点: 一、什么是并发和竞态? 并发: 多个执行单元同时发生; 执行单元是指:进程和中断; 竞态:多个执行单元对

weixin_47273317的博客 240

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

linux设备驱动程序-第五章(并发和竞态)学习总结

一、前言 目前为止,我们很少关注并发问题——亦即,当系统试图一次完成多个任务时会产生什么结果。但是,对并发的管理是操作系统编程中核心的一个问题。为了响应现代硬件和应用程序的需求,Linux内核已经发展到同时发展更多事情的年代了。设备驱动程序开发者必须在开始设计时考虑并发因素,并且还必须对内核提供的并发管理设施有坚实的理解。 竟态会导致共享数据的非控制访问。发生错误的访问模式,会产生非预期的结果。因...

Feng_8071的博客 469

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

Linux设备驱动程序学习(3)-并发和竞态

Linux设备驱动程序学习(3)-并发和竞态今天进入《Linux设备驱动程序(第3版)》第五章并发和竞态的学习。对并发的管理是操作系统编程中核心的问题之一。 并发产生竞态,竞态导致共享数据的非法访问。因为竞态是一种极端低可能性的事件,因此程序员往往会忽视竞态。但是在计算机世界中,百万分之一的事件可能没几秒就会发生,而其结果是灾难性的。一、并发及其管理竞态通常是作为对资源的共享访问结果而产生的。在设计自己的驱动程序时,第一个要记住的规则是:只要可能,就应该避免资源的共享。若没有并发访问,就不会有竞态。这种思想

tanxs001的专栏 594

Linux设备驱动程式学习(3)-并发和竞态

 今天进入《Linux设备驱动程式(第3版)》第五章并发和竞态的学习。 对并发的管理是操作系统编程中核心的问题之一。 并发产生竞态,竞态导致共享数据的非法访问。因为竞态是一种极端低可能性的事件,因此程式员往往会忽视竞态。但是在电脑世界中,百万分之一的事件可能没几秒就会发生,而其结果是灾难性的。一、并发及其管理 竞态通常是作为对资源的共享访问结果而产生的。在设计自己的驱动程式时,第一个要记住的规则是

luckdog01的专栏 377

Linux设备驱动程序学习笔记5——并发和竞态

 1、 并发及其管理竞态通常作为对资源的共享访问结果而产生。资源共享的硬规则:在单个执行线程之外共享硬件或软件资源的任何时候,因为另外一个线程可能产生对该资源的不一致观察,因此必须显式地管理对该资源的访问。一个重要的规则:当内核代码创建了一个可能和其他内核部分共享的对象时,该对象必须在还有其他组件引用自己时保持存在(并正确工作)。2、 信号量和互斥体临界区:在任意给定的时刻

wxiaozhe的专栏 2247

Hasen的linux设备驱动开发学习之旅--linux设备驱动中的并发与竞态

/**  * author:hasen  * 参考:《linux设备驱动开发详解》  */ 1、并发与竞态 并发(concurrency)指的是多个执行单元同时、并行被执行,而并发的执行单元对共享资源(软件上的全局变量,静态变量等)的访问则很容易导致竞态(race conditions). 主要的竞态发生在以下几种情况: (1)对称多处理(SMP)的多个CPU (2)单CPU内进程

android_hasen博客 1258

嵌入式LINUX驱动学习之8竞态和并发相关问题(一)中断屏蔽

嵌入式LINUX驱动学习之8竞态和并发相关问题(一)中断屏蔽一、中断屏蔽的方法头文件及说明二、代码举例(内核空间)三、代码举例(用户空间)四、测试 一、中断屏蔽的方法头文件及说明 //源码位置:include/linux/irqflags.h #define local_irq_save(flags) \ do { \

weixin_47273317的博客 166

Linux设备驱动程序学习(5)-并发和竞态

并发及其管理 1、并发(concurrency)指的是多个执行单元同时、并行被执行,而并发的执行单元对共享资源(硬件资源和软件上的全局变量、静态变量等)的访问则很容易导致竞态(race condition)。   2、在设计自己的驱动程序时,第一个要记住的规则是,只要可能,就应该避免资源的共享。如果没有并发的访问,也就不会有竞态的产生。因此,仔细编写的内核代码应具有最少的共享。这种思想的最明

wangsh217的专栏 964

嵌入式LINUX驱动学习之8竞态和并发相关问题(四)信号量

嵌入式LINUX驱动学习之8竞态和并发相关问题(四)信号量一、头文件、函数及说明附A.1附1.2 信号量运行在进程中,可以因超时或中断信号而结束,可以进行休眠操作 一、头文件、函数及说明 //源码位置:include/linux/semaphore.h //结构体对象:struct semaphore {} struct semaphore { raw_spinlock_t lock; unsigned int count;

weixin_47273317的博客 137
上一篇: Linux驱动学习——中断、定时器
下一篇: Linux驱动学习——等待队列
kitestar
博客等级 码龄15年 3粉丝 17原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值