驱动———互斥和同步

本文主要讨论了驱动程序中出现竞态条件的问题及其解决方案。竞态条件是指多个路径同时访问同一数据导致数据紊乱。为了解决这个问题,文章介绍了互斥和同步的概念,如中断屏蔽、原子变量、自旋锁、读写锁、顺序锁和信号量等,并详细阐述了各种同步机制的优缺点及使用场景。
摘要由CSDN通过智能技术生成

这个主要是为了解决竞态的问题。

什么是竞态?
就是对于同一个数据,由于有很多路径同时访问(这里的同时访问,可能发生在多核处理器的状态,在单核上是指假的同时访问,接下来会讲同时访问的请况)。由于这样多个文件访问读取修改,这样就会造成数据紊乱。从而大概率会使很多路径读写等操作的数据都是不正确的。这在内核这种级别的代码来讲是致命的。为了解决这种问题于是引入了互斥的同步的概念。
eg:
我在内核中有一个全局变量:i= 5;
我正常的的程序是要执行一个i++的操作。那么我实际上执行的指令是三条

ldr r1,[ro]					//读栈r0的数据放到 r1寄存器里   这里假设了I 存储在ro的位置
add r1,r1 ,#1			//i++
str  r1,[ro]					//把r1的数据再放到栈里ro的位置,这样就完成了自加

如果这时候我在执行第一条指令把5的数据放到r1中。
这时候突然就来了一条中断,这时候我不得不停下来,去处理中断信息,
但是很巧的是,我的中断处理函数,也是要对这个i 进行++ 操作。
于是我的 i 就变成了6 .
处理完了我就放回去处理第二条指令add r1,r1 ,#1,然后第三条 str r1,[ro];
这时候你就会发现,你的 i 还是 6 ,但是实际上它自加了俩次。应该等于7.这就是竞态带来的后果。

竞态可能会发生的情况:同时访问
1)在多核处理器情况下,几个处理器真正的同时操作同一个数据。
2)像上面一样,我正常程序正在处理ing的时候,中断来了,而且,它也要处理同一个东西。
3)在多线程中,我一个线程要处理这个东西,然后我在等一个信号,就是我阻塞了,这时候我就会休眠,把cpu让给其它线程。那么如果那个线程也处理这个数据。当我等到唤醒信号,我又去处理这个东西的时候。也会数据紊乱。
4)抢占内核的多进程环境——我们的进程是有优先级的,我低优先级的程序的资源会被高优先级抢占。这核中断一样也会数据紊乱。
5)软中断和tasklet——中断下半部的情况也可能发生对共享资源的同时访问。

什么数据会有竞态:共享资源
常见的有:全局变量,静态变量,硬件里面存储的信息(包括cpu的寄存器数据,其它硬件资源的数据),共同使用的同一段动态内存(堆区)。
————————————————————————————————————————————
好,前面讲了一大堆竞态的情况,那么主要是怎么预防这种情况

1、中断屏蔽。
适用于你知道什么中断会同时使用共享资源的情况。————这种方法局限性太大了,首先你要知道,什么中断会会同时使用共享资源,然后它还不能预防其它竞态可能会发生的情况,只能针对中断这一种。

unsigned long fiags;
local_irq_save(flags);
i ++ ;   //共享资源
local_orq_restore(flags);

2、原子变量。
如果一条对整形的共享资源的操作是不可分割的,即只用一条汇编指令就可以完成,这样只要声明他是原子变量就不用考虑竞态了。
因为我们可以使用原子变量操作接口对共享资源进行操作。比如加减乘除,读写置一清零。。。。等一系列操作。
api:

声明:

atomic_t i =ATOMIC_INIT(5)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值