嵌入式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 原子操作特点:
一、什么是并发和竞态?
并发: 多个执行单元同时发生;
执行单元是指:进程和中断;
竞态:多个执行单元对共享资源进行同时访问,形成竞争关系的状态
所以形成竞态必须具备:
1、要有多个执行单元
2、要有共享资源(程序中的全局变量、操作的各种寄存器)
3、要同时发生访问
总结:避免竞态的方式就是当一个执行单元在访问共享资源时,让CPU可以不中断的访问共享资源,
这个访问共享资源期间,CPU资源不会发生切换。我们称这个访问共享资源的操作具有原子性,
即:访问共享资源的操作是一个整体,不可再分。
二、什么是互斥访问
当一个执行单元在访问共享资源时,其它执行单元禁止访问这个临界区域。
三、互斥访问的方法:
1、中断屏蔽2、自旋锁系列 3、 信号量4、原子操作
3.1 中断屏蔽
3.1.1 中断屏蔽的特点:
1、单CPU的进程与进程的抢占本身是基于软中断实现2、中断屏蔽能够解决以下竞态问题:1)中断和中断:硬件中断和软件中断,软件中断和软件中断(软件中断分为高优先级和低优先级两种)2)中断和进程:硬件中断和进程软件中断和进程3)进程之间的抢占3、中断屏蔽不能解决多核引起的竞态异常
3.1.2 中断屏蔽的互斥访问过程:
当一个执行单元在访问共享资源前,先开启中断屏蔽,一旦屏蔽的中断信号,任务将接收不到中断信号,此时也就没有了高低优先级的进程抢占资源,也不会有其它硬件中断或软件中断打断任务的执行,此执行单元也就可以踏踏实实对共享资源进行操作,当操作完成后,应当立即恢复中断。注:多核时可能会引起异常
3.1.3 使用中断屏蔽可能带来的问题和需要注意的事项
由于中断屏蔽实现的方式是将中断功能禁止,而linux操作系统很多机制(tasklet、 软件定时器、硬件定时器、按键等等)都和中断密切相关,长时间使用中断屏蔽,会给系统带来影响,所有使用中断屏蔽操作的共享资源代码执行速度要快,因休眠类操作会释放资源,故不能使用中断屏蔽,多核下也可能会导致中断屏蔽功能失效,也不推荐使用。
3.2 自旋锁
3.2.1 自旋锁的特点:
1、自旋锁必须要附加在某个共享资源上(访问共享资源前加锁,操作完成后解锁);2、要访问共享资源之前,要先获取自旋锁,如果获取自旋锁失败,此任务会原地空转(处于忙等待),直到获取到自旋锁3、如果获取自旋锁成功,可以访问共享资源 ,但访问共享资源 的代码执行速度要快,且不能有休眠操作;4、操作完共享资源,一定要记得释放自旋锁注:1、可以解决多核、单CPU进程与进程的抢占问题,但无法解决中断引起的异常。2、在中断和休眠的引起的异常场景中,自旋锁不适用。
3.2.1 衍生自旋锁的特点
1、衍生自旋锁必须要附加在某个共享资源上(访问共享资源前加锁,操作共享资源完毕释放衍生自旋锁),2、在访问共享资源前要先获取 衍生自旋锁,如果获取衍生自旋锁失败(处于忙等待),直到获取到衍生自旋锁,3、获取衍生自旋锁成功后,就可以访问共享资源了,但操作共享资源的代码执行速度一定要性,更不能有休眠操作,4、操作完共享资源后,一定要记得释放衍生自旋锁,注:衍生自旋锁可以解决所有的竞态引用的异常(相当于自旋锁 + 中断屏蔽);
3.3 信号量
3.3.1 信号量特点:
1、内核中的信号量和应用程序中的信号量一模一样,2、信号量又称睡眠锁,本质上基于自旋锁,只是多加了一个休眠功能,3、想获取信号量访问共享资源的进程,在没有获取信号量时,此进程将进行休眠操作(此进程会释放占用的CPU资源)4、一旦获取信号量进程,可以访问共享资源,对共享资源进行操作,操作完毕释放信号量,并且唤醒之前休眠的等待进程;注:信号量用于进程中;
3.4 原子操作
3.4.1 原子操作特点:
1、原子操作能够解决所有的竞态引起的异常,2、原子操作可以分为:位原子操作整形原子操作3、位原子操作:位操作具有原子性,也就是在位操作时,不允许发生CPU资源切换,如果驱动要对共享资源进行位操作,可以考虑位原子操作相关的函数实现互斥访问,4、整形原子操作:整形数的操作具有原子性,如果驱动 中对共享资源进行整形操作(++ --等),此时可以考虑使用内核提供的整形原子操作函数来实现互斥访问,linux内核对于整形原子操作提供了专有的数据类型:atomic , 又称整形原子变量拘束类型,并且对整形原子变量进行的访问操作时,一事实上要利用内核提供的整形原子操作函数,才能达到互斥访问的效果。