当内核空间中的一个进程持有 spin_lock
时,由于以下任何条件之一,该进程都无法被抢占:
- 进程的时间片用尽
- 高优先级进程变得可运行
- 中断发生
但是,如果该进程阻塞、睡眠或显式调用 schedule()
,则可以让出处理器。我的理解正确吗?
当内核空间中的一个进程持有 mutex_lock
时,是否会由于上述第1、2、3种情况而被抢占?
当内核空间中的一个进程持有 spin_lock
时,由于以下任何条件之一,该进程都无法被抢占:
但是,如果该进程阻塞、睡眠或显式调用 schedule()
,则可以让出处理器。我的理解正确吗?
当内核空间中的一个进程持有 mutex_lock
时,是否会由于上述第1、2、3种情况而被抢占?
目前的自旋锁实现使用两种完全分离的机制来确保互斥,一个用于处理跨处理器互斥,另一个用于处理本地处理器线程和中断处理程序。
有自旋锁本身,只用于在两个或多个处理器核之间提供互斥。任何遇到被锁定的自旋锁的处理器都基本上被卡住,直到另一个处理器释放它。自旋锁在单处理器系统上没有任何作用 - 除了增加完全死锁的可能性 - 因此通常会在内核编译时删除。
为了提供本地处理器互斥,spin_lock() 调用 preempt_disable()(在抢占式调度系统中)以防止持有锁时运行任何其他线程;同样,spin_lock_irqsave() 也执行 local_irq_save() 的等效操作以禁用中断,以防止在本地处理器上运行其他任何事情。
从上面可以看出,使用自旋锁可能会使整个机器变慢,因此应仅在短时间内使用自旋锁,并且不要在持有锁时执行可能导致重新调度的任何操作。
而 mutex_lock 的情况则完全不同 - 只有尝试访问锁的线程受到影响,如果一个线程遇到被锁定的互斥体,则会进行重新调度。因此,mutex_locks 不能在中断(或其他原子)上下文中使用。
mutex_lock()
可以在 IRQ 上下文中使用,当 IRQ 处理程序保证是一个线程时。 - 0andriy