Linux内核自旋锁和互斥锁期间的抢占

12

当内核空间中的一个进程持有 spin_lock 时,由于以下任何条件之一,该进程都无法被抢占:

  1. 进程的时间片用尽
  2. 高优先级进程变得可运行
  3. 中断发生

但是,如果该进程阻塞、睡眠或显式调用 schedule(),则可以让出处理器。我的理解正确吗?

当内核空间中的一个进程持有 mutex_lock 时,是否会由于上述第1、2、3种情况而被抢占?


你看到这个帖子了吗:https://dev59.com/fk_Ta4cB1Zd3GeqPA3EE - PhD
是的,我已经阅读了它。但那个帖子似乎很混乱。那不是我在我的问题中所要表达的意思。 - nitin_cherian
在持有自旋锁时,您不能阻塞或schedule()(好吧,你可以,但结果不会太好)。 - ninjalj
1个回答

19

目前的自旋锁实现使用两种完全分离的机制来确保互斥,一个用于处理跨处理器互斥,另一个用于处理本地处理器线程和中断处理程序。

  • 有自旋锁本身,只用于在两个或多个处理器核之间提供互斥。任何遇到被锁定的自旋锁的处理器都基本上被卡住,直到另一个处理器释放它。自旋锁在单处理器系统上没有任何作用 - 除了增加完全死锁的可能性 - 因此通常会在内核编译时删除。

  • 为了提供本地处理器互斥,spin_lock() 调用 preempt_disable()(在抢占式调度系统中)以防止持有锁时运行任何其他线程;同样,spin_lock_irqsave() 也执行 local_irq_save() 的等效操作以禁用中断,以防止在本地处理器上运行其他任何事情。

从上面可以看出,使用自旋锁可能会使整个机器变慢,因此应仅在短时间内使用自旋锁,并且不要在持有锁时执行可能导致重新调度的任何操作。

而 mutex_lock 的情况则完全不同 - 只有尝试访问锁的线程受到影响,如果一个线程遇到被锁定的互斥体,则会进行重新调度。因此,mutex_locks 不能在中断(或其他原子)上下文中使用。


mutex_lock() 可以在 IRQ 上下文中使用,当 IRQ 处理程序保证是一个线程时。 - 0andriy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接