前段时间去腾讯面试被问到了这个问题。以前编程时一直使用却没有细究过内核是使用什么系统调用来实现的,所以回来赶紧做个整理(发现种类远比预想的多)。
参考资料:关于linux中多进程(线程)同步和互斥,内核抢占和中断
先放结论:Linux内核同步方法列表如下:中断屏蔽、原子操作、自旋锁、读写自旋锁、顺序锁、信号量、读写信号量、BKL(大内核锁)
零:并发与竞态:
并发(concurrency)指的是多个执行单元同时、并行被执行,而并发的执行单元对共享资源的访问则很容易导致竞态(race conditions)。
在linux中,主要的竞态发生在如下几种情况:
1、对称多处理器(SMP)多个CPU:特点是多个CPU使用共同的系统总线,因此可访问共同的外设和存储器。
2、单CPU内进程与抢占它的进程
3、中断(硬中断、软中断、Tasklet、底半部)与进程之间
只要并发的多个执行单元存在对共享资源的访问,竞态就有可能发生。
如果中断处理程序访问进程正在访问的资源,则竞态也会会发生。多个中断之间本身也可能引起并发而导致竞态(中断被更高优先级的中断打断)。
访问共享资源的代码区域被称为临界区,临界区需要以某种互斥机制加以保护,中断屏蔽,原子操作,自旋锁,和信号量都是linux设备驱动中可采用的互斥途径。
一:中断屏蔽:
在单CPU范围内避免竞态的一种简单方法是在进入临界区之前屏蔽系统的中断。
由于linux内核的进程调度等操作都依赖中断来实现,内核抢占进程之间的并发也就得以避免了。
中断屏蔽的使用方法:
local_irq_disable()//屏蔽中断
//临界区
local_irq_enable()//开中断
特点:在屏蔽中断期间所有的中断都无法得到处理,因此长时间的屏蔽是很危险的,有可能造成数据丢失甚至系统崩溃,