OS如何保持对计算机的控制权?

前面我们提到:OS希望在保持控制权的同时,为用户提供高性能的并发。

那么OS究竟是如何保持对计算机的控制权呢?这似乎是一个令人迷惑(但很重要!)的问题:OS也是进程,自然也需要计算资源。那既然我们希望一直保持OS的控制权,难道OS需要一直占用计算资源么?当然不是这样。

在微内核OS中,一般有两种模式 ------ 内核模式(Kernel Mode)和 用户模式(User Mode),普通用户进程基本都运行在用户模式中,只能执行一些一般的、基本的操作。那不一般的操作(我们称之为"特权操作")有哪些呢?比如I/O操作、中断处理、时钟管理、还有相当重要的进程调度操作等,这些"特权操作"只能在内核模式中由操作系统进行,而用户模式下则不能执行任何特权操作。

上述内核模式与用户模式的关系类似于什么呢?其实有点像父母给小孩子的安全屋:所有比较危险的东西(比如带电的插座、窗户等)都被保护起来了,小孩子可以在里边安全的活动。但是一旦他想做任何"危险行为",就应该找他的父母来完成那些"危险行为"。

类似的,一旦某个程序希望执行某个特权操作,它就会调用OS内核(syscall)来执行,这样CPU的控制权就被原先的程序移交给了OS。

好,看起来我们已经保证了OS的控制权:通过用户进程主动syscall移交控制权。但是这个方式没有解决另外一个问题:如果一个进程一直不愿意交出CPU控制权怎么办?这样的进程很容易实现:一个while(true);无限循环就行。对于这些不友好的进程,我们该如何处理才能保证OS的控制权?

(想一想,你可以想到的!)

没错,我们可以定时将控制权移交给OS,这可以利用时钟(如石英振荡器)来实现,每隔一段时间定时syscall,强制将计算机控制权移交给OS就行,当然这需要硬件中断的支持。

综上,现在我们有两种方式来保证OS对计算机的控制权:1 友好的进程会主动syscall来移交控制权;2 对于不友好的进程,我们使用定时中断的方式获得控制权。

当然,上述两种方式还带来了2个小问题:

1. 所有用户模式的进程在将控制权移交给OS后(或主动或被动),它都相当于从原本的运行状态被硬生生地打断了。那么它下一次运行的时候,我们是不是需要将计算机恢复到它被打断之前的状态,从而接着运行呢?没错,当然是需要的,我们可以用Process Control Block来实现,这个过程就叫Context Switch ------ 上下文切换

2. OS或主动或被动地获得控制权后,都必须要决定接下来要运行哪个用户进程,那么OS是如何来决定接下来运行什么进程的呢?这就要通过调度算法 ------ Scheduler来实现。