操作系统调度程序如何重新获得CPU的控制权?

我最近开始学习CPU和操作系统是如何工作的,而且我对使用提供多任务操作系统的单CPU机器的操作有些困惑。

因此,假设我的机器只有一个CPU,这意味着在任何时候只有一个进程可以运行。

现在,我只能假定操作系统用来控制访问贵重CPU时间的调度程序也是一个过程。

因此,在这台机器中,用户进程或调度系统进程在任何给定的时间点运行,但不是两者都运行。

所以这是一个问题:

一旦调度程序将CPU的控制权交给另一个进程,又如何重新获得CPU时间来再次运行以执行其调度工作呢? 我的意思是,如果当前正在运行的任何进程没有放弃(产生)CPU,那么调度器本身如何再次运行并确保正确的多任务处理呢?

到目前为止,我一直在想,如果用户进程通过系统调用请求I / O操作,那么在系统调用中,我们可以确保调度器再次分配一些CPU时间。 但我甚至不确定这是否有效。

另一方面,如果用户进程本质上是CPU限制的,那么从这个angular度来看,它可以永远运行,从不让其他进程,甚至是调度器再次运行。

假设一个时间片调度,我不知道如何调度程序可以分割执行另一个进程的时间,甚至没有运行?

我真的很感谢你在这方面可以提供的任何见解或参考。

OS设置一个硬件定时器( 可编程间隔定时器或PIT),每N毫秒产生一次中断。 该中断被传递给内核,并且用户代码被中断。

它和其他硬件中断一样工作。 例如,您的磁盘在完成IO时会强制切换到内核。

谷歌“中断”。 中断是multithreading的核心,抢占内核如Linux / Windows。 没有中断,操作系统将永远不会做任何事情。

在调查/学习的过程中,尽量忽视提到第一段中的“定时中断”,“循环”和“时间片”,“量子”的任何解释 – 如果实际上不是错误的,那么这些解释是危险的误导。

操作系统中的中断有两种:

硬件中断 – 由来自外围设备的实际硬件信号启动的中断。 这些可以在任何时候(几乎)发生,并且可以从任何可能正在运行的线程切换到驱动程序中的代码。

软件中断 – 由当前正在运行的线程的OS调用启动的那些中断。

任何一个中断都可能要求调度程序创build正在等待就绪/正在运行的线程,或者导致正在等待/正在运行的线程被抢占。

最重要的中断是来自外设驱动程序的硬件中断 – 那些使得线程能够从磁盘,NIC卡,鼠标,键盘,USB等等等待IO的线程。使用抢占式内核的首要原因以及所有的问题locking,同步,信号等等,因为这样的系统具有非常好的性能,因为硬件外设可以快速地使线程准备好/运行,以便从硬件中等待数据,没有任何延迟导致不会产生或等待一个周期的线程定时器RESCHEDULE。

导致周期性计划运行的硬件计时器中断非常重要,因为许多系统调用都有超时情况,例如,来自外设的响应比预期的要长。

在多核系统上,操作系统具有可引起其他核心硬件中断的处理器间驱动程序,从而允许操作系统中断/调度/分配多个核心的线程。

在严重超载的盒子或运行CPU密集型应用程序的系统(less数应用程序)中,操作系统可以使用周期性定时器中断,以及由此产生的调度,循环一系列比可用内核数量更多的就绪线程因此允许每个可用CPU资源的份额。 在大多数系统中,这种情况很less发生,并不重要。

我对这个呐喊感到抱歉,但是每次我看到“量子”,“放弃其余的时间片”,“循环”等等,我只是不知所措。

为了补充@ usr的答案,引用了解了解Linux内核 :

schedule()函数

schedule()实现调度器。 它的目标是在runqueue列表中find一个进程,然后将CPU分配给它。 它被直接或以一种懒惰的方式被几个内核例程调用。 […]

懒惰的调用

通过将current [process]的need_resched字段设置为1,调度程序也可以以惰性方式调用。由于在继续执行用户模式过程之前总是检查此字段的值(请参见“返回从中断和例外“第4章),schedule()肯定会在将来一段时间被调用。