字符设备驱动(10)-互斥与同步:中断屏蔽

基本概念    

        现代操作系统基本都是多任务系统,多个任务并发执行可能同时使用同一个资源,也可能会有依赖关系。其中可能会被多个任务同时使用的资源被称为共享资源。多任务并行执行时,如果在一个时刻同时操作同一个资源,会引起资源的错乱,这种错乱情形被称为竞态。操作共享资源的代码段被称为临界区。

        在用户态程序中,造成竞态场景有:

        (1)多进程:当一个进程因为等待资源不可用时,就会主动让出CPU,内核会调度另外一个进程来执行。

        (2)多线程:同一进程不同线程使用同一个全局变量、静态变量等。

        (3)多处理器或多核CPU:同一时刻,可以在多个处理器上或多核上并发执行多个程序,使用相同的硬件的寄存器,或内核中同一段内存。

          (4)抢占内核的多进程:如果一个进程在执行时发生系统调用,进入到内核,由内核代替该进程完成相应的操作,此时如果有一个更高优先级的进程准备就绪,内核判断在可抢占的条件成立的情况下可以抢占当前进程,然后去执行更高优先级的进程。

        在内核态,在上面基础上多了中断的场景:

        (5)硬件中断:当处理器允许中断,一个内核路径可能在任何一个时候被一个外部中断打断。

        (6)软中断和tasklet:在硬件中断快要返回之前,执行软中断和tasklet。

        解决竞态的一个方法是互斥,就是对共享资源进行串行化访问,即在一条执行路径上访问共享资源时,不允许其他执行路径来访问共享资源。用户态的手段有互斥锁、读写锁、自旋锁、信号量等,而内核态中,除了这些手段外,还有中断屏蔽、原子变量、RCU等。
       而任务有依赖关系是一种更为复杂的互斥,而互斥是一种特殊的同步。也就是说互斥是两个任务之间不可以同时运行,他们会相互排斥,必须等待一个线程运行完毕,另一个才能运行,而同步也是不能同时运行,但他是必须要安照某种次序来运行相应的线程(也是一种互斥)!因此互斥具有唯一性和排它性,但互斥并不限制任务的运行顺序,即任务是无序的。而同步的任务之间则有顺序关系。

        用户态程序解决任务之间依赖关系的机制有信号量,内核态除了它,还增加了专门的机制:完成量。        

中断屏蔽

        上面列举的场景中,其中一个场景是一条内核执行路径被中断打断,如果在访问共享资源之前就现将中断屏蔽掉(关闭),然后再访问共享资源,等共享资源访问完成后,再重新使能中断,就能避免这种竞态产生。如果明确知道是哪一个中断会带来竞态,就关闭相应的中断,避免关闭本地CPU的全局中断或者本地的全局中断。本地中断屏蔽(关闭)函数为:

local_irq_disable(); /* 屏蔽中断 */
. . .
critical section /* 临界区*/
. . .
local_irq_enable();  /* 开中断*/

        但不推荐使用,推荐使用:

unsigned long flags;
local_irq_save(flags); /* 屏蔽中断及保存中断标记位 */
. . .
critical section /* 临界区*/
. . .
local_irq_restore(flags);  /* 开中断及恢复中断标记位*/

        因为,如果中断在屏蔽之前本身就是屏蔽的,那么在local_irq_enable()后就会将屏蔽的中断错误的使能,从而造成中断使能状态前后不一致。

        中断屏蔽只能禁止和使能本地CPU内的中断,因此,并不能解决多CPU引发的竞态,并且中断屏蔽的时间不宜过长,否则会影响系统的性能,所有在内核中,使用中断屏蔽的场景很有限。

        比如全局变量i是共享资源,则使用中断屏蔽的例子为:

unsigned long flags;
local_irq_save(flags); /* 屏蔽中断及保存中断标记位 */
i++;/* 临界区*/
local_irq_restore(flags);  /* 开中断及恢复中断标记位*/

tobecontinue

​ 每周三、周六更新

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值