wuyouwuyou

Linux中常见互斥之我见

0
阅读(2668)

从内核中资然共享数据区(临界区)和性质、所有代码执行路径等方面分别对互斥情形进行分析,从而得出如何选择最佳互斥机制,使得系统可行并且实时性强。

1临界区

1)为了保证对数据修改的原子性而临界区很小时,则应该采用自旋锁。因为自旋锁具有不能再数据共享区停留的时间太长得特性,所以它可以节省上下文切换时间,使系统的性能增强。

2)如果临界区很大或有共享设备的时候,则常用信号量。如果还要防止中断(包括软中断)的打扰,要用自旋锁的衍生锁。当多进程争夺资然时,如果竞争不上,会有上下文切换,进程可以去睡眠,可是处理器不会停,会接着运行其他的执行路径。

3)如果临界区存在引起阻塞的代码,这是则应该采用信号量。因为阻塞则意味着进程的切换,如果切换出去的进程再企图获得本自旋锁,就会引起死锁。

4)如果一个进程在执行一个临界区的代码时,发生了中断,这时就采用关中断。这样中断函数就不可能调用这个临界区的代码,否则它进入的话就会产生死锁,

2 内核执行路径

内核中的执行路径主要有以下几种情形:

1) 没有进程上下文,如中断、异常、bottom_half、自陷等,则不能进行上下文切换;

2) 用户进程的内核态,有进程上下文,主要是代表进程在执行系统调用等;

3) 多CPU处理系统中具有相同的执行路径。

这样,通过判断要互斥的数据会被这些因素中的哪几个来存取,就可以决定具体使用哪种形式的spin lock。(注意:以下使用spin_lock一×××等为自旋锁的衍生锁如下表所示。 值得指出的是,对同一个数据的互斥,在不同的内核执行路径中,所用的形式有可能不同。

3 单处理器和多处理器

随着Linux操作系统的成功,在单处理器中,主要遇到的是中断和bottom_half的问题,因此,开关中断就可以了。但是在多处理器中,因为Linux是支持对称多处理器(SMP)的操作系统,所以内核也必须跟踪现有的CPU并在它们之间调度工作,从而保证进程的顺利进行。即使是最简单形式的只有两个CPU的多处理器的计算机也具有许多新的可能性和困难。原因之一,让两个CPU在同一内核就像和相同的(共享的)硬件下共同工作是一件非常复杂的任务。一个适合于单CPU系统的内核同时用于两个或更多CPU时将会失败。为了让Linux支持SMP,用户必须重编译内核,将肋SMP选项设为Yes。且需要spin lock来帮助,这二个部分结合起来使用。

自旋锁主要针对多处理器或单处理器但内核可抢占(2.6内核)的情况,而对于单CPU和内核不支持抢占的系统自旋锁退化为空操作。在单CPU和内核可抢占的系统中,自旋锁持有期间内核的抢占将被禁止。尽管用了自旋锁可以保证临界区不受别的CPU和本CPU内的抢占进程打扰,但是得到锁的代码路径在执行临界区的时候还可能受到中断和下半部(bottom half)的影响。为了防止这种影响,就需要用自旋锁的衍生。