9. linux 内核 自旋锁vs信号量

旋锁和信号量都是解决互斥问题的基本手段,面对特定的情况,应该如何进行选择呢?
选择的依据是临界区的性质和系统的特点。
从严格意义上说,信号量和自旋锁属于不同层次的互斥手段,前者的实现依赖于后者。在信号量本身的实现上,为了保证信号量结构存取的原子性,在多CPU 中需要自旋锁来互斥。

信号量是进程级的,用于多个进程之间对资源的互斥,虽然也是在内核中,但是该内核执行路径是以进程的身份,代表进程来争夺资源的。如果竞争失败,会发生进程上下文切换,当前进程进入睡眠状态,CPU将运行其他进程。鉴于进程上下文切换的开销也很大,因此,只有当进程占用资源时间较长时,用信号量才是较好的选择。

当所要保护的临界区访问时间比较短时,用自旋锁是非常方便的,因为它节省上下文切换的时间。但是 CPU 得不到自旋锁会在那里空转直到其他执行单元解锁为止,所以要求锁不能在临界区里长时间停留,否则会降低系统的效率。由此,可以总结出自旋锁和信号量选用的 3 项原则。

  • 当锁不能被获取时,使用信号量的开销是进程上下文切换时间Tsw,使用自旋锁的开销是等待获取自旋锁(由临界区执行时间决定)Tcs,若 Tcs 比较小,应使用自旋锁,若Tcs很大,应使用信号量。
  • 信号量所保护的临界区可包含可能引起阻塞的代码,而自旋锁则绝对要避免用来保护包含这样代码的临界区。因为阻塞意味着要进行进程的切换,如果进程被切换出去后,另一个进程企图获取本自旋锁,死锁就会发生。
  • 信号量存在于进程上下文,因此,如果被保护的共享资源需要在中断或软中断情况下使用,则在信号量和自旋锁之间只能选择自旋锁。当然,如果一定要使用信号量,则只能通过down_trylock()方式进行,不能获取就立即返回以避免阻塞。

注:

自旋锁:忙等锁

信号量:抢不到资源就休眠等待

原文地址:https://www.cnblogs.com/standardzero/p/12551100.html