Chinaunix

标题: 关于自旋锁的一个很弱的问题 [打印本页]

作者: yushang    时间: 2009-04-01 09:52
标题: 关于自旋锁的一个很弱的问题
线程持有自旋锁时为什么不能休眠呢
作者: junonly    时间: 2009-04-01 11:23
如果另外一个线程需要该锁,就可能会死锁(至少是性能下降,不知道什么时候休眠的线程能被再次调度)
作者: yushang    时间: 2009-04-01 11:56
lock            lock
...               ...   
                        / lock
           =>         \ unlock
...               ...   
unlock        unlock
假设线程被抢占或者中断了,无论是哪种方式,都等价于在线程中插入了另外一个执行路径,如果在该执行路径上会竞争相同的自旋锁,死锁就发生了,如果不竞争相同的自旋锁,死锁还是不会发生的,这样理解对吧
作者: Cyberman.Wu    时间: 2009-04-01 12:55
spin lock基本上就是一个死循环不停地测试某个值有没有变成预期的吧,所谓得到其实就是改了某个值而已,在改回去之后如果休眠了任何其它进程(不管是本CPU还是其它的)再想得到这个spin lock就会在内核态忙等了,多数会导致死机。
作者: ruanunix    时间: 2009-04-01 16:30
自旋锁不休眠,信号量用来休眠
作者: new_learner    时间: 2009-04-11 21:09
原帖由 yushang 于 2009-4-1 09:52 发表
线程持有自旋锁时为什么不能休眠呢


如果线程能休眠,那为什么不用信号量呢?
自旋锁一般用于不能发生休眠(不会产生进程上下文切换)的内核路径,比如中断。



原帖由 yushang 于 2009-4-1 11:56 发表
lock            lock
...               ...   
                        / lock
           =>         \ unlock
...               ...   
unlock        unlock
假设线程被抢占或者中断了,无论是哪种 ...

如果使用了自旋锁,线程是不会发生内核抢占的,可以看下自旋锁的实现:
在非SMP(UP)系统中:

  1. #define spin_lock(lock)                        _spin_lock(lock)

  2. #define _spin_lock(lock)                        __LOCK(lock)

  3. #define __LOCK(lock) \
  4.   do { preempt_disable(); __acquire(lock); (void)(lock); } while (0)

  5. preempt_disable()禁止了内核抢占
复制代码


在SMP中

  1. #define spin_lock(lock)                        _spin_lock(lock)

  2. void __lockfunc _spin_lock(spinlock_t *lock)
  3. {
  4.         preempt_disable();
  5.         _raw_spin_lock(lock);
  6. }

  7. preempt_disable()禁止了内核抢占
复制代码


如果你怕中断处理程序同时访问被中断的进程正在持有的自旋锁,可以调用这样的函数:

  1. spin_lock_irqsave(lock, flags);

  2. spin_unlock_irqrestore(lock, flags) ;
复制代码

这样就万无一失了。




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2