中断屏蔽 原子操作 信号量

在设计自己的驱动程序时,第一个要记住的规则是: 只要可能,就应该避免资源的共享。 若没有并发访问,就不会有竞态。 这种思想的最明显的应用是避免使用全局变量。

临界区: 临界区 指的是一个访问共用资源(例如:共用设备或是共用存储器)的程序片段,而这些共用资源又无法同时被多个 线程 访问的特性, 临界区同一时间只能被一个进程访问


一、中断屏蔽:
local_irq_disable()和local_irq_enable()都只能禁止和使能本CPU 内的中断,因此,并不能解决SMP 多
CPU 引发的竞态。因此,单独使用中断屏蔽通常不是一种值得推荐的避免竞态的方法,它适宜与自旋锁联
合使用

    local_irq_disable() 和 local_irq_enable() 配对使用;只有我们知道中断并未在其他地方被禁用的情况下,才能使用这个版        本

    local_irq_save() 和  local_irq_restore()  配对使用。
    local_irq_disable() 和 local_irq_save() 都可以禁止中断,但不同的是后者可以保存中断状态。
    local_irq_restore() 在使能中断的同时还恢复了由 local_irq_save() 所保存的中断状态。



二、原子操作:
UniProcessor 单处理器平台:因指令执行中不可能被插入,即使中断也是在指令执行切换中再发生,所以原子操作没必要。
SMP多处理器平台:WINDOWS 用 指令前缀lock用于锁定前端串行总线(FSB)  linux atomic.h
目前来说内核中 原子操作多用来做计数使用 ,其它情况最常用的是两种锁以及它们的变种 : 一个是自旋锁,另一个是信号量 。我们     下面就来着重介绍一下这两种锁机制。

    三、信号量

   ------------------------------------------------------
   Linux中的信号量是一种睡眠锁。如果有一个任务试图获得一个已被持有的信号量时,信号量会将其推入等待队列,然后让其睡      眠。这时处理器获得自由去执行其它代码。当持有信号量的进程将信号量释放后,在等待队列中的一个任务将被唤醒,从而便可以    获得这个信号量。
   信号量的睡眠特性,使得信号量适用于锁会被长时间持有的情况;只能在进程上下文中使用,因为中断上下文中是不能被调度的;    另外当代码持有信号量时,不可以再持有自旋锁。

   信号量基本使用形式为:
   static DECLARE_MUTEX(mr_sem);//声明互斥信号量
   if(down_interruptible(&mr_sem))
   //可被中断的睡眠,当信号来到,睡眠的任务被唤醒
   //临界区
   up(&mr_sem);

  





信号量和自旋锁区别
------------------------------------------------------
信号量适合于保持时间较长的情况,它们会导致调用者睡眠,因此只能在进程上下文使用自旋锁适合于保持时间非常短的情况,它可以在任何上下文使用

自旋锁保持期间是抢占失效的,而信号量和读写信号量保持期间是可以被抢占的。

自旋锁不能递归使用

自旋锁对信号量
------------------------------------------------------
需求 建议的加锁方法

低开销加锁 优先使用自旋锁
短期锁定 优先使用自旋锁
长期加锁 优先使用信号量
中断上下文中加锁 使用自旋锁
持有锁是需要睡眠、调度 使用信号量

处理器总处于以下三种状态之一:

1、内核态,运行于进程上下文,内核代表进程运行于内核空间;
2、内核态,运行于
中断上下文,内核代表硬件运行于内核空间;
3、用户态,运行于用户空间。

用户空间的应用程序,通过系统调用,进入内核空间。这个时候用户空间的进程要传递 很多变量、参数的值给内核,内核态运行的时候也要保存用户进程的一些寄存 器值、变量等。所谓的“进程上下文”,可以看作是用户进程传递给内核的这些参数以及内核要保存的那一整套的变量和寄存器值和当时的环境等。

硬件通过触发信号,导致内核调用中断处理程序,进入内核空间。这个过程中,硬件的 一些变量和参数也要传递给内核,内核通过这些参数进行中断处理。所谓的“ 中断上下文”,其实也可以看作就是硬件传递过来的这些参数和内核需要保存的一些其他环境(主要是当前被打断执行的进程环境)。

LINUX完全注释中的一段话:

当一个进程在执行时,CPU的所有寄存器中的值、进程的状态以及堆栈中的内容被称 为该进程的上下文。当内核需要切换到另一个进程时,它需要保存当前进程的 所有状态,即保存当前进程的上下文,以便在再次执行该进程时,能够必得到切换时的状态执行下去。在LINUX中,当前进程上下文均保存在进程的任务数据结 构中。在发生中断时,内核就在被中断进程的上下文中,在内核态下执行中断服务例程。但同时会保留所有需要用到的资源,以便中继服务结束时能恢复被中断进程 的执行。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值