multithreading - 先发制人如何运作?

标签 multithreading algorithm operating-system kernel scheduled-tasks

据我了解,调度程序执行以下操作:

  1. 计算任务的时间片(这可能取决于算法)。
  2. 切换任务 - 理想的调度程序喜欢在 O(1) 中执行。一个好的调度算法提供 O(logN) 复杂度。选择新任务的标准再次取决于调度算法。

我的问题是先发制人。例如,创建了一个新任务并且它需要立即运行(并且它确实满足条件 - 例如它比当前运行的任务具有更高的优先级)。

调度程序如何知道有更高优先级的新任务可用并且需要运行。我们需要在内核实现中有一些控制代码来检测这样的任务条目并调用调度程序来保存当前正在运行的任务的状态并重新安排新任务。我想了解有关此类软件实体的更多详细信息。

此外,我希望这段代码被安排在 CPU 上运行,以控制“调度程序”并使调度程序切换任务。

请告知这是如何实现的,或者我的理解可能存在一些差距。

提前致谢

最佳答案

理解这一点的最好方法是阅读像“X 操作系统的设计”这样的书,其中 X 是 {Unix、Linux、BSD...} 之一。您应该找到有关上下文切换的一章和有关调度程序的一章。你也可以看看 https://en.wikipedia.org/wiki/Context_switchhttps://en.wikipedia.org/wiki/Scheduling_%28computing%29#Linux ,但这本书可能更好。

基本上,当用户代码执行系统调用(例如创建新进程,或释放信号量,或...)或当您获得时钟中断时,或当您获得某种其他中断时,用户进程的运行状态总是被转储到内存中,这样内核代码就可以在不扰乱用户进程的情况下运行。完成此操作后,正在运行的用户进程与任何其他可运行的用户进程没有太大区别。

作为系统调用、中断或其他服务所需工作的一部分,系统可以注意到有一个新的可运行进程或之前不可运行的一些其他进程现在可运行,并询问调度程序更新最高优先级可运行进程的概念。它还可能注意到调度量程刚刚过期,并要求调度程序运行完整的重新调度。

一旦内核代码完成了它的工作,它可能会看到调度程序已经标记了最高优先级的可运行进程,内核代码将从内存中读取该进程的状态并返回给它,而不用太担心它是否是在系统调用之前运行的进程或其他任何东西。

异常(exception):曾几何时,机器担心转储和恢复浮点寄存器的成本,内核模式并不真正需要,因为它可以被编写成从不做浮点。在这种情况下,保存/恢复代码可能会被编写为除非必须,否则它不会保存浮点寄存器,并且内核可能会在恢复过程中检查它是否正在切换到新进程,并且需要转储并恢复浮点寄存器。据我所知,东西可能仍然会这样做,或者可能会有一些更现代的状态,只有在流程真正发生变化时才会保存和恢复。但这实际上只是两种情况下的一个细节。

关于multithreading - 先发制人如何运作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31900532/

相关文章:

multithreading - 复制工作线程的字符串

algorithm - 具有固定长度子串的最长公共(public)子序列

java - 获取指定文件路径的file.separator

c# - 多线程格式化datagridview行?

c# - 在c#中,如何在多线程环境下迭代IEnumerable

algorithm - 像素矩阵到坐标

java - 如何用Java写入OS系统日志?

linux - 如何让Alpine OS安装.run文件?

c++ - 在不同线程中使用map::empty和map::insert

algorithm - 如何删除具有单个子节点的树节点的子节点