Skip to content
This repository has been archived by the owner on May 6, 2021. It is now read-only.

Commit

Permalink
ch8
Browse files Browse the repository at this point in the history
  • Loading branch information
wizardforcel committed Jul 10, 2016
1 parent b4563e5 commit 2aee482
Showing 1 changed file with 55 additions and 0 deletions.
55 changes: 55 additions & 0 deletions ch8.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,58 @@

在多任务的系统中,每个进程都允许运行一小段时间,叫做“时间片”或“quantum”。在上下文切换的过程中,内核会设置一些硬件计数器,它们会在时间片的末尾产生中断。当中断发生时,内核可以切换到另一个进程,或者允许被中断的进程继续执行。操作系统中做决策的这一部分叫做“调度器”。

## 8.3 进程的生命周期

当进程被创建时,操作系统会为进程分配包含进程信息的数据结构,称为“进程控制块”(PCB)。在其它方面,PCB跟踪进程的状态,这包括:

+ 运行(Running),如果进程正在运行于某个核心上。
+ 就绪(Ready),如果进程可以但没有运行,通常由于就绪进程数量大于内核的数量。
+ 阻塞(Blocked),如果进程由于正在等待未来的事件,例如网络通信或磁盘读取,而不能运行。
+ 终止(Done):如果进程运行完毕,但是带有没有读取的退出状态信息。

下面是一些可导致进程状态转换的事件:

+ 一个进程在运行中的程序执行类似于`fork`的系统调用时诞生。在系统调用的末尾,新的进程通常就绪。之后调度器可能恢复原有的进程(“父进程”),或者启动新的进程(“子进程”)。
+ 当一个进程由调度器启动或恢复时,它的状态从就绪变为运行。
+ 当一个进程被中断,并且调度器没有选择使它恢复,它的状态从运行变成就绪。
+ 如果一个进程执行不能立即完成的系统调用,例如磁盘请求,它会变为阻塞,并且调度器会选择另一个进程。
+ 当类似于磁盘请求的操作完成时,会产生中断。中断处理器弄清楚哪个进程正在等待请求,并将它的状态从阻塞变为就绪。
+ 当一个进程调用`exit`时,中断处理器在PCB中储存退出代码,并将进程的状态变为终止。

## 8.4 调度

就像我们在2.3节中看到的那样,一台计算机上可能运行着成百上千条进程,但是通常大多数进程都是阻塞的。大多数情况下,只有一小部分进程是就绪或者运行的。当中断发生时,调度器会决定那个进程应启动或恢复。

在工作站或笔记本上,调度器的首要目标就是最小化响应时间,也就是说,计算机应该快速响应用户的操作。响应时间在服务器上也很重要,但是调度器同时也可能尝试最大化吞吐量,它是单位时间内所完成的请求。

调度器通常不需要关于进程所做事情的大量信息,所以它基于一些启发来做决策:

+ 进程可能被不同的资源限制。执行大量计算的进程是计算密集的,也就是说它的运行时间取决于得到了多少CPU时间。从网络或磁盘读取数据的进程是IO密集的,也就是说如果数据输入和输出更快的话,它就会更快,但是在更多CPU时间下它不会运行得更快。最后,与用户交互的程序,在大多数时间里可能都是阻塞的,用于等待用户的动作。操作系统有时可以将进程基于它们过去的行为分类,并做出相应的调度。例如,当一个交互型进程不再被阻塞,应该马上运行,因为用户可能正在等待回应。另一方面,已经运行了很长时间的CPU密集的进程可能就不是时间敏感的。
+ 如果一个进程可能会运行较短的时间,之后发出了阻塞的请求,它可能应该立即运行,出于两个原因:(1)如果请求需要一些时间来完成,我们应该尽快启动它,(2)长时间运行的进程应该等待短时间的进程,而不是反过来。作为类比,假设你在做苹果馅饼。面包皮需要5分钟来准备,但是之后需要半个小时的冷却。而馅料需要20分钟来准备。如果你首先准备面包皮,你可以在其冷却时准备馅料,并且可以在35分钟之内做完。如果你先准备馅料,就会花费55分钟。

大多数调度器使用一些基于优先级的调度形式,其中每个进程都有可以调上或调下的优先级。当调度器运行时,它会选择最高优先级的就绪进程。

下面是决定进程优先级的一些因素:

+ 具有较高优先级的进程通常运行较快。
+ 如果一个进程在时间片结束之前发出请求并被阻塞,就可能是IO密集型程序或交互型程序,优先级应该升高。
+ 如果一个进程在整个时间片中都运行,就可能是长时间运行的计算密集型程序,优先级应该降低。
+ 如果一个任务长时间被阻塞,之后变为就绪,它应该提升为最高优先级,便于响应所等待的东西。
+ 如果进程A在等待进程B的过程中被阻塞,例如,如果它们由管道连接,进程B的优先级应升高。
+ 系统调用`nice`允许进程降低(但不能升高)自己的优先级,并允许程序员向调度器传递显式的信息。

对于运行普通工作负载的多数系统,调度算法对性能并没有显著的影响。简单的调度策略就足够好了。

## 8.5 实时调度

但是,对于与真实世界交互的程序,调度非常重要。例如,从传感器和控制马达读取数据的程序,可能需要以最小的频率完成重复的任务,并且以最大的响应时间对外界事件做出反应。这些需求通常表述为必须在“截止期限”之前完成的“任务”。

调度满足截止期限的任务叫做“实时调度”。对于一些应用,类似于Linux的通用操作系统可以被修改来处理实时调度。这些修改可能包括:

+ 为控制任务的优先级提供更丰富的API。
+ 修改调度器来确保最高优先级的进程在固定时间内运行。
+ 重新组织中断处理器来保证最大完成时间。
+ 修改锁和其它同步机制(下一章会讲到),允许高优先级的任务预先占用低优先级的任务。
+ 选择保证最大完成时间的动态内存分配实现。

对于更苛刻的应用,尤其是实时响应是生死攸关的领域,“实时操作系统”提供了专用能力,通常比通用操作系统拥有更简单的设计。

0 comments on commit 2aee482

Please sign in to comment.