进程调度案例分析与常见疑惑1:为何不能调度?

本文深入探讨了Linux内核调度器在不支持内核抢占和支持内核抢占情况下的工作原理,分析了当0号线程创建并运行内核线程1和线程2后,调度器如何在时钟中断下决定是否调度新进程。通过场景分析和流程详解,解释了新进程如何执行以及调度的本质,帮助读者理解中断与调度的密切关系。
摘要由CSDN通过智能技术生成

微信公众号:奔跑吧linux社区

本文节选自《奔跑吧linux内核》第二版卷1第9.3.5章

现在JD有半价抢购活动,如果您觉得本文还可以,千万不要错过哟!

https://item.jd.com/13051268.html

1. 问题引入

假设Linux内核只有3个内核线程(见图9.15),0号线程创建了内核线程1和内核线程2,它们永远不会退出。当系统时钟中断到来时,时钟中断处理函数会检查是否有进程需要调度。当有进程需要调度时,调度器会选择运行线程1或者线程2。

假设0号线程先运行,那么在这个场景下会发生什么情况?
这是一个有意思的问题,涉及调度器的实现机制、中断处理、内核抢占、新建进程如何被调度、进程切换等知识点。我们只有把这些知识点都弄明白了,才能真正搞明白这个问题。

2.场景分析

这个场景中的主要操作步骤如下。
(1)start_kernel()运行在0号线程里。0号线程创建了内核线程1和内核线程2。函数调用关系是start_kernel()→kernel_thread()→_do_fork()。在_do_fork()函数会创建新线程,并且把新线程添加到调度器的就绪队列中。0号线程创建内核线程1和内核线程2后,进入while死循环,0号线程不会退出,它正在等待被调度出去。
(2)产生时钟中断。处理器采用时钟定时器来周期性地提供系统脉搏。时钟中断是普通外设中断的一种。调度器利用时钟中断来定时检测当前正在运行的线程是否需要调度。
(3)当时钟中断检测到当前线程需要调度时,设置need_resched标志位。
(4)当时钟中断返回时,根据Linux内核是否支持内核抢占来确定是否需要调度,下面分两种情况来讨论。
 支持内核抢占的内核:发生在内核态的中断返回时,检查当前线程的need_resched标志位是否置位,如果置位,说明当前线程需要调度。
 不支持内核抢占的内核:发生在内核态的中断在中断返回时不会检查是否需要调度。

不支持内核抢占的内核

在不支持内核抢占功能的Linux内核(见图9.16)里,即使0号线程的need_resched标志位置位了,Linux内核也不会调度内核线程1或者内核线程2来运行。只有发生在用户态的中断返回或者系统调用返回用户空间时,才会检查是否需要调度。处理流程如下所示。

(1)发生时钟中断。触发时钟中断时当前进程(线程)有可能在用户态执行,也可能在内核态执行。如果进程运行在用户态时发生了中断,那么会进入异常向量表的el0_irq汇编函数;如果进程运行在内核态时发生了中断,那么会进入异常向量表的el1_irq汇编函数中。在本场景中,因为3个线程都是内核线程

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值