先发制人如何运作?
How pre-emption works?
据我了解,调度程序执行以下项目:
- 计算任务的时间片(这可能取决于算法)。
- 切换任务 - 理想的调度程序喜欢在 O(1) 中执行。一个好的调度算法提供 O(logN) 复杂度。选择新任务的标准再次取决于调度算法。
我的问题是先发制人。例如,创建了一个新任务,它需要立即 运行(并且它确实满足条件 - 例如它比当前 运行ning 任务具有更高的优先级)。
调度程序如何知道 运行 有可用且需要更高优先级的新任务。我们需要在内核实现中有一些控制代码来检测此类任务条目并调用调度程序来保存当前 运行ning 任务的状态并重新安排新任务。我想了解有关此类软件实体的更多详细信息。
此外,我希望此代码在 CPU 上安排到 运行 以控制 "scheduler" 并使调度程序切换任务。
请告知这是如何实现的,或者我的理解可能存在一些差距。
提前致谢
理解这一点的最好方法是阅读像 "The design of the X Operating System" 这样的书,其中 X 是 {Unix、Linux、BSD...} 之一。您应该找到有关上下文切换的一章和有关调度程序的一章。您也可以看看 https://en.wikipedia.org/wiki/Context_switch and https://en.wikipedia.org/wiki/Scheduling_%28computing%29#Linux,但是这本书可能更好。
基本上,当用户代码执行系统调用时(例如创建新进程,或释放信号量,或...)或当您获得时钟中断时,或当您获得其他某种类型的中断时中断,用户进程的 运行ning 状态总是被转储到内存中,这样内核代码就可以 运行 而不会弄乱用户进程。完成此操作后,运行ning 的用户进程与任何其他 运行nable 用户进程没有太大区别。
作为系统调用、中断或其他服务所需工作的一部分,系统可以注意到有一个新的 运行nable 进程或其他一些不是 运行nable before now is 运行nable,并要求调度程序更新其最高优先级的概念运行nable进程。它还可能注意到调度量程刚刚过期,并要求调度程序 运行 完成重新调度。
一旦内核代码完成它的工作,它可能会看到调度程序已标记最高优先级 运行nable 进程,并且内核代码将从内存中读取该进程的状态并且 return 到它而不用太担心它是否是系统调用之前 运行ning 的进程或其他任何东西。
例外:曾几何时,机器担心转储和恢复浮点寄存器的成本,内核模式并不真正需要,因为它可以被编写成从不进行浮点。在这种情况下,save/restore 代码可能会被编写为除非必须,否则它不会保存浮点寄存器,并且内核可能会在恢复过程中检查它是否正在切换到新进程,并且需要转储和恢复浮点寄存器。据我所知,东西可能仍然会这样做,或者可能会有一些更现代的状态,只有在流程真正发生变化时才会保存和恢复。但这实际上只是两种情况下的一个细节。
据我了解,调度程序执行以下项目:
- 计算任务的时间片(这可能取决于算法)。
- 切换任务 - 理想的调度程序喜欢在 O(1) 中执行。一个好的调度算法提供 O(logN) 复杂度。选择新任务的标准再次取决于调度算法。
我的问题是先发制人。例如,创建了一个新任务,它需要立即 运行(并且它确实满足条件 - 例如它比当前 运行ning 任务具有更高的优先级)。
调度程序如何知道 运行 有可用且需要更高优先级的新任务。我们需要在内核实现中有一些控制代码来检测此类任务条目并调用调度程序来保存当前 运行ning 任务的状态并重新安排新任务。我想了解有关此类软件实体的更多详细信息。
此外,我希望此代码在 CPU 上安排到 运行 以控制 "scheduler" 并使调度程序切换任务。
请告知这是如何实现的,或者我的理解可能存在一些差距。
提前致谢
理解这一点的最好方法是阅读像 "The design of the X Operating System" 这样的书,其中 X 是 {Unix、Linux、BSD...} 之一。您应该找到有关上下文切换的一章和有关调度程序的一章。您也可以看看 https://en.wikipedia.org/wiki/Context_switch and https://en.wikipedia.org/wiki/Scheduling_%28computing%29#Linux,但是这本书可能更好。
基本上,当用户代码执行系统调用时(例如创建新进程,或释放信号量,或...)或当您获得时钟中断时,或当您获得其他某种类型的中断时中断,用户进程的 运行ning 状态总是被转储到内存中,这样内核代码就可以 运行 而不会弄乱用户进程。完成此操作后,运行ning 的用户进程与任何其他 运行nable 用户进程没有太大区别。
作为系统调用、中断或其他服务所需工作的一部分,系统可以注意到有一个新的 运行nable 进程或其他一些不是 运行nable before now is 运行nable,并要求调度程序更新其最高优先级的概念运行nable进程。它还可能注意到调度量程刚刚过期,并要求调度程序 运行 完成重新调度。
一旦内核代码完成它的工作,它可能会看到调度程序已标记最高优先级 运行nable 进程,并且内核代码将从内存中读取该进程的状态并且 return 到它而不用太担心它是否是系统调用之前 运行ning 的进程或其他任何东西。
例外:曾几何时,机器担心转储和恢复浮点寄存器的成本,内核模式并不真正需要,因为它可以被编写成从不进行浮点。在这种情况下,save/restore 代码可能会被编写为除非必须,否则它不会保存浮点寄存器,并且内核可能会在恢复过程中检查它是否正在切换到新进程,并且需要转储和恢复浮点寄存器。据我所知,东西可能仍然会这样做,或者可能会有一些更现代的状态,只有在流程真正发生变化时才会保存和恢复。但这实际上只是两种情况下的一个细节。