放了一个五一,回来工作就没状态。在拿起spin lock时候才发现里面实现的还是比较复杂的。
话说互斥和同步有semaphore , mutex等等。但是呢semaphore的性能没mutex好(对于为什么mutex比semaphore好,可以参看mutex-design.txt),而且比mutex大。所以现在广泛的使用mutex。
看了mutex的结构体后发现里面其实使用了spin,于是选择先学习spin。
在学习时发现一篇文章,http://blog.chinaunix.net/uid-23247212-id-3644336.html。里面讲的还是比较细。所以转发来存下。现在主要需要知道怎么使用spin。
对于spin的代码里面呢,在上边的那个博客里面已经讲的清楚了。
下面总结一下spin的使用情况。(具体情况请参考ldd3和《linux内核设计与实现》第八章 内核同步方法)
1:应用自旋锁的核心规则是任何代码必须在持有自旋锁时, 是原子性的. 它不能睡眠; 事实上, 它不能因为任何原因放弃处理器, 除了服务中断(并且
有时即便此时也不行),(一般来说这种是不能有中断的,如果中断来了,导致进入相同的代码,那就麻烦了。会死锁。而且同时在spin代码里面是禁止了内核抢占的)
2:在持有自旋锁时,不能睡眠,睡眠会影响系统的性能,没人知道你要睡多久。也许你不会醒来。编写会在自旋锁下执行的代码需要注意你调用的每个函数.
3:对于在持有自旋锁的地方,如果发生了中断,那么很可能造成这个处理器也需要获得这个锁,那么当中断处理在自旋, 非中断代码不能运行来释放锁. 这个处理器将永远自旋
这样系统就死了,对于多处理器的系统而言是这个处理器死了。避免这种情况在持有自旋锁时禁止中断。在自旋锁里面已经提供了相应的函数,所以在使用时要特别注意选对函数没有。
4:自旋锁必须一直是尽可能短时间的持有. 你持有一个锁越长, 另一个进程可能不得不自旋等待你释放它的时间越长, 它不得不完全自旋的机会越大. 长时间持有锁也阻止了当前处理器调度。
void spin_lock(spinlock_t *lock); /*一般的spin函数*/
void spin_lock_irqsave(spinlock_t *lock, unsigned long flags); /*用于中断的版本,且不需要关注以前有没有关中断*/
void spin_lock_irq(spinlock_t *lock); /*用于中断的版本,且需要关注以前有没有关中断*/
void spin_lock_bh(spinlock_t *lock) /*这个版本只是关软中断,硬件中断还是开启的*/
所以这四个版本在使用时,需要特别注意情况。
阅读(968) | 评论(0) | 转发(0) |