现在的位置: 首页 > 综合 > 正文

linux 驱动对并发资源访问的保护

2013年02月14日 ⁄ 综合 ⁄ 共 1435字 ⁄ 字号 评论关闭

 首先从其它地方搬来一些对这些术语的解释:
 1、并发(concurrency)指的是多个执行单元同时、并行被执行,而并发的执行单元对共享资源(硬件资源和软件上的全局变量、静态变量等)的访问则很容易导致竞态(race condition)。

 2、在设计自己的驱动程序时,第一个要记住的规则是,只要可能,就应该避免资源的共享。如果没有并发的访问,也就不会有竞态的产生。因此,仔细编写的内核代码应具有最少的共享。这种思想的最明显应用就是避免使用全局变量。
但是资源的共享是不可避免的,如硬件资源的本质就是共享、指针传递等。

 3、资源共享的硬规则:
 (1)在单个执行线程之外共享硬件或软件资源的任何时候,因为另外一个线程可能产生对该资源的不一致观察,因此必须显示地管理对该资源的访问。
 (2)当内核代码创建了一个可能和其他内核部分共享的对象时,该对象必须在还有其他组件引用自己时保持存在(并正确工作)。

 然后为了应对并发控制所带来的后果,linux提供了以下的机制:
 自旋锁,信号量,互斥体,中断屏蔽,原子操作

 网上,书上都有资料细说这些方式的使用方法,我就不用再说一遍了,我比较关心他们的应用场景和区别:
 1,自旋锁--好比上WC,我进去了,门一锁,你想要进来是进不来的,必须得等我解锁出来了,你才能进来。它是多个进程操作的时候,当前只有一个进程可以访问临界区的资源,其它进程只能等(这种等还是需要跟信号量区分开的,自旋锁的等是在不停的敲门询问,可以轮到我了不,所以它是比较消耗资源的)。所以记住它的应用场景只能是在占用锁的时间极短的情况。
      读写自旋锁--自旋锁的更细化的类型。比如是在读写一个文件,这个文件是记录一些信息的,在这种情况下其实是可以允许多个用户读的,但不允许一个读一个写或多个写,这就刚好可以用上读写自旋锁了。
      顺序锁--我稍微看了下,就是读写自旋锁的进化类型,它只禁止用户同时写,允许同时读,同时读写。效率比读写自旋锁更高,但是限制了被保护的共享资源不含有指针,这样我觉得应用场景更受限制了。

 2,信号量--信号量使用方式跟自旋锁类似,区别在于获取不到信号量时,进程不会原地打转而是进入休眠等待状态。它的应用场景跟自旋锁也因这个不同的等而不同,进程在等的时候会进入睡眠状态,CPU进程就会发生上下文切换,这部分开销是比较大的,所以它适合临界资源运行时间比较长的情况。简单来说短用自旋锁,长用信号量。它还有重要的一点哦,想要达到互斥的概念,信号量的初始值得为1哦。

 3,互斥体--跟信号量的原理一致,它跟信号量使用区别应该是:互斥体用于线程,信号量用于进程和线程。

 4,中断屏蔽--这个是因为中断有时会打断互斥资源的操作,比如我在写文件A的时候,还没有释放锁,中断来了,而中断线程里的操作刚又是写文件A,我又跑到中断线程里去执行写文件A的操作,完了,我这下申请不到锁了,因为中断打断前没有释放锁。为了避免这种情况,有时会采用中断屏蔽的方式,我屏蔽中断后拿锁,写完文件A再释放锁,然后取消屏蔽。
    中断屏蔽的时间要尽可能的短,故一般是配合自旋锁使用。

 5,原子操作--这里我倒真还没有想到切实的应用场景,网上说用于资源计数,TCP/IP协议栈中有使用。
 
 我对linux接触没多久,感觉这个跟WINCE还是有些差别的(CE有临界区的函数,互斥可以用于进程间的)。如果有说的不对的地方大家只管拍砖,相信后面的深入大家都会越来越好,理解也越来越深。

 

抱歉!评论已关闭.