最近在看<精通LInux设备驱动与开发>
把一些好的说法放在这里,方便自己今后查阅;
临界区:访问共享资源的代码区域。
自旋锁和互斥体是保护内核临界区的两种机制;
自旋锁:可以确保同时只有一个线程进入临界区。其他想进入临界区的线程必须不停地原地打转,直到第一个线程释放自旋锁。
这里的线程不是内核线程,而是执行线程.
自旋锁的基本形式如下:
spin_lock(&mr_lock);
//临界区
spin_unlock(&mr_lock);
因为自旋锁在同一时刻只能被最多一个内核任务持有,所以一个时刻只有一个线程允许存在于临界区中。
这点很好地满足了对称多处理机器需要的锁定服务。在单处理器上,自旋锁仅仅当作一个设置内核抢占的开关。
如果内核抢占也不存在,那么自旋锁会在编译时被完全剔除出内核。
简单的说,自旋锁在内核中主要用来防止多处理器中并发访问临界区,防止内核抢占造成的竞争。
另外自旋锁不允许任务睡眠(持有自旋锁的任务睡眠会造成自死锁——因为睡眠有可能造成持有锁的内核任务被重新调度,
而再次申请自己已持有的锁),它能够在中断上下文中使用。
与自旋锁不同的是,互斥体在进入一个被占用的临界区之前不会原地打转,而是使当前线程进入睡眠状态。
如果要等待的时间较长,互斥体比自旋锁更合适,因为自旋锁会消耗CPU资源。
如何来判断什么时候使用自旋锁,什么时候使用互斥体呢?
1.如果临界区需要睡眠,只能用互斥体,因为在获得自旋锁后进行调度、抢占以及在等待队列上睡眠都是非法的;
2.由于互斥体在面临竞争的情况下将当前线程置于睡眠状态,因此,在中断处理函数中,只能使用自旋锁;