为什么自旋锁中不能睡眠

spin_lock()的实现

#define spin_lock(lock) _spin_lock(lock)

#define _spin_lock(lock) __LOCK(lock)

#define __LOCK(lock) \

do { preempt_disable(); __acquire(lock); (void)(lock); } while (0)

  preempt_disable()”,这个调用的功能是“关抢占”(在spin_unlock中会重新开启抢占功能)。

  假设有A,B两个进程,A如果拿到锁以后,内核的抢占暂时被禁止。然后A休眠了,切换到另一个进程B(注意,这不是抢占,是进程自己放弃CPU)。

如果A是通过spin_lock()拿到自旋锁,等到进程B想要获得这个锁时发生了死锁,尽管B的时间片会被用完,但由于内核抢占被禁止了,所以B不会被调度出去。

如果A是通过spin_lock_irq()或spin_lock_irqsave()拿到自旋锁,中断是被禁止的,时钟中断不会被响应,B的时间片不会被更新,会一直执行B。

互斥锁与信号量的区别

信号量​:用来解决进程/线程之间的同步和互斥问题的一种通信机制,是用来保证两个或多个关键代码不被并发调用。

    信号量(Saphore)由一个值和一个指针组成,指针指向等待该信号量的进程,信号量的值表示相应资源的使用情况。

信号量的值表示相应资源的使用情况。信号量S>=0时,S表示可用资源的数量。执行一次down()操作意味着请求分配一个资源,因此S的值减1;

当S<0时,表示已经没有可用资源,S的绝对值表示当前等待该资源的进程数。请求者必须等待其他进程释放该类资源,才能继续运行。

而执行一个up()操作意味着释放一个资源,因此S的值加1;若S<0,表示有某些进程正在等待该资源,因此要唤醒一个等待状态的进程,使之运行下去。

互斥锁​:互斥锁同样也是对线程间(不能对进程)同步和互斥的一种另一种机制。

    当一个线程占用了当前共享资源,使用互斥锁将其lock住之后,其他线程就无法访问,必须等到unlock之后,其他线程才能利用共享资源里面的内容。

信号量与互斥锁区别

1.信号量可用于进程/线程,而互斥锁只能用于线程

2.信号量会在释放资源时,检查信号量值,如果睡眠队列不为空(S<0),则唤醒其他等待此信号量的进程,而互斥锁释放时不会唤醒其他等待的线程。

3.互斥锁必须由同一个线程来获得、释放;信号量可以是一个线程获得,另一个线程释放。