操作系统调度程序如何重新控制CPU



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

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

现在,我只能假设操作系统用来控制访问宝贵CPU时间的调度器也是一个进程。

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

所以这里有一个问题:

一旦调度器将CPU的控制权交给另一个进程,它如何重新获得CPU时间来再次运行自己来完成调度工作?我的意思是,如果当前运行的任何给定进程都没有产生CPU,那么调度器本身怎么能再次运行并确保正确的多任务处理?

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

另一方面,如果有问题的用户进程本身就有CPU限制,那么从这个角度来看,它可以永远运行,永远不会让其他进程,甚至调度器再次运行。

假设时间切片调度,我不知道调度程序如何在另一个进程不运行的情况下为其执行时间切片?

如果您能在这方面提供任何见解或参考,我将不胜感激。

操作系统设置硬件计时器(可编程间隔计时器或PIT),每N毫秒生成一次中断。该中断被传递到内核,并且用户代码被中断。

它的工作原理与任何其他硬件中断一样。例如,当磁盘完成IO时,它将强制切换到内核。

Google"interrupts"。中断是多线程、抢占式内核(如Linux/Windows)的核心。如果没有中断,操作系统将永远不会做任何事情。

在调查/学习时,尽量忽略第一段中提到"定时器中断"、"循环"one_answers"时间片"或"量子"的任何解释——如果不是真的错的话,它们是危险的误导。

从操作系统的角度来看,中断有两种类型:

  • 硬件中断——由外围设备的实际硬件信号启动的中断。这些情况几乎可以在任何时候发生,并将执行从可能运行的线程切换到驱动程序中的代码。

  • 软件中断——由当前运行线程的操作系统调用启动的中断。

任何一种中断都可能请求调度程序使正在等待的线程准备就绪/正在运行,或者导致正在等待/正在运行的线程被抢占。

最重要的中断是来自外围驱动程序的硬件中断——那些使线程做好准备的中断,这些线程正在等待磁盘、NIC卡、鼠标、键盘、USB等的IO。使用抢占式内核的首要原因,以及锁定、同步、信令等所有问题。,这类系统具有非常好的IO性能,因为硬件外围设备可以快速使等待来自该硬件的数据的线程做好准备/运行,而不会因线程不屈服或等待定期计时器重新调度而产生任何延迟

导致周期性调度运行的硬件定时器中断很重要,因为许多系统调用都会超时,以防外围设备的响应花费的时间超过应有的时间。

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

在严重过载的盒子上,或者那些运行CPU密集型应用程序的盒子上(少数),操作系统可以使用周期性的定时器中断和由此产生的调度,在一组大于可用内核数量的就绪线程中循环,并允许每个线程共享可用CPU资源。在大多数系统中,这种情况很少发生,也不太重要。

每次我看到"量子"、"放弃剩余的时间片段"、"循环赛"等等,我都会感到尴尬。。。

为了补充@usr的回答,引用了《理解Linux内核:》

时间表()功能

schedule()实现了调度器。其目标是找到进程,然后将CPU分配给它由几个内核例程直接或以惰性方式调用。[…]

延迟调用

也可以通过设置当前[进程]的need_sched字段为1。由于检查了字段总是在恢复执行用户模式之前生成进程(请参阅中的"从中断和异常返回"一节第4章),schedule()肯定会在某个时候调用未来时间。

最新更新