1

问题前稍微讨论一下。Linux 2.4 内核是非抢占式的,所以如果我们在内核模式下进行系统调用时需要进行上下文切换,我们只需执行 set_need_resched 来引发一个标志,然后当我们返回用户模式时,我们检查标记并进行上下文切换。

让我们将其与具有抢占式内核的 linux 2.6 进行比较。我们不能只取 2.4 的内核并将 set_need_resched(提升标志)更改为 schedule()(重新调度的指令执行),因此在 linux 内核 2.6 中有一个计数器 preempt_count,它每次在 spin_lock() 上增加并在自旋解锁()。

实际上,这个字段“preempt_count”决定了内核是否可以被抢占。例如,在从时钟中断返回时,如果条件:

(current->need_resched == 1) && (current->preempt_count == 0)

为真,则内核执行上下文切换。

问题是为什么 linux 2.6 的内核在持有自旋锁类型的锁时会阻止抢占。

如果内核不阻止抢占,可能会发生什么情况?你能给我一个尽可能详细的具体例子吗?

谢谢你。

4

1 回答 1

0

你读过像互斥锁或信号量这样的可休眠锁吗?

在他们的情况下,如果无法获取锁,线程可以让自己进入睡眠状态,例如借出其优先级,以便锁所有者(如果处于睡眠状态)可以更快地完成工作。特别是,想要获取锁的线程可能在锁所有者计划继续运行的 CPU 上运行。

另一方面,自旋锁的假设是没有人睡觉——这意味着特别忙的等待(即停留在 cpu 上)不会阻塞锁所有者。如果持有锁,则所有者正在某处运行。但是,假设它睡着了。这意味着等待线程会浪费时间,因为所有者无法恢复工作。只有在调度器确定它足够之后它才会被抢占,但是服务员和所有者之间没有建立关系。所以特别是可能是服务员会回到cpu上继续忙等待,而锁的所有者仍然没有机会运行。

所以至少这将是一个巨大的性能问题。在实践中,它只会导致内核无法向前推进的高负载下的活锁。

于 2017-12-30T23:01:34.640 回答