linux 2.6调度和抢占 - preempt_count使用

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了linux 2.6调度和抢占 - preempt_count使用相关的知识,希望对你有一定的参考价值。

在问题面前进行一些讨论。 Linux 2.4内核不是preemtive,所以如果我们在内核模式下执行系统调用时需要上下文切换,我们只需要set_need_resched来提升标志然后当我们回到用户模式时,我们检查标记并执行上下文切换。

让我们将其与具有抢占式内核的linux 2.6进行比较。我们不能只取2.4的内核并将set_need_resched(raise flag)更改为schedule()(重新安排的指令执行),所以在linux内核2.6中有一个计数器preempt_count,它每次都会在spin_lock()上增加并减少spin_unlock()保护。

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

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

是的,然后内核执行上下文切换。

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

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

谢谢。

答案

你读过有关可互换的锁,如互斥锁或信号量吗?

在他们的情况下,如果不能进行锁定,则线程可以使自己进入睡眠状态,例如优先考虑锁定所有者(如果睡觉)可以更快地完成工作。特别是,可能希望获取锁的线程在cpu上运行,锁所有者被安排继续。

另一方面,对于自旋锁,假设没有人睡觉 - 这意味着特别是忙等待(即停留在cpu上)不会阻止锁拥有者。如果锁定,则所有者正在某处运行。但是,让我们说它进入了睡眠状态。这意味着等待线程将浪费时间旋转,因为所有者无法恢复工作。只有在调度程序确定它之后它才会被抢占,但是服务员和所有者之间没有建立任何关系。所以特别是服务员可能会回到cpu继续忙着等待,而锁主人仍然没有机会跑。

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

以上是关于linux 2.6调度和抢占 - preempt_count使用的主要内容,如果未能解决你的问题,请参考以下文章

Linux唤醒抢占----Linux进程的管理与调度(二十三)

Linux 内核 内存管理优化内存屏障 ③ ( 编译器屏障 | 禁止 / 开启内核抢占 与 方法保护临界区 | preempt_disable 禁止内核抢占源码 | 开启内核抢占源码 )

Linux 内核调度器 ④ ( sched_class 调度类结构体分析 | yield_task 函数 | heck_preempt_curr 函数 | task_struct 函数 )

Linux进程切换 同步处理

linux 进程调度3

为啥“barrier()”足以禁用或启用抢占?