
1.1.2 多进程/多线程时代的调度器需求
多进程/多线程的操作系统解决了阻塞的问题,一个进程阻塞CPU可以立刻切换到其他进程中去执行,而且调度CPU的算法可以保证在运行的进程都可以被分配到CPU的运行时间片。从宏观来看,似乎多个进程是在同时被运行,如图1.2所示。

图1.2 多线程/多进程执行顺序
图1.2为一个CPU通过调度器切换CPU时间轴的情景。如果未来满足宏观上每个进程/线程是一起执行的,则CPU必须切换,每个进程会被分配到一个时间片中。
提示 时间片(Timeslice)又称为“量子(Quantum)”或“处理器片(Processor Slice)”,是分时操作系统分配给每个正在运行的进程微观上的一段CPU时间(在抢占内核中是从进程开始运行直到被抢占的时间)。现代操作系统(如:Windows、Linux、Mac OS X等)允许同时运行多个进程——例如,可以在打开音乐播放器听音乐的同时用浏览器浏览网页并下载文件。事实上,虽然一台计算机通常可能有多个CPU,但是同一个CPU永远不可能真正地同时运行多个任务。在只考虑一个CPU的情况下,这些进程“看起来像”同时运行的,实则是轮番穿插地运行,由于时间片通常很短(在Linux上为5~800ms),用户不会感觉到。
时间片由操作系统内核的调度程序分配给每个进程。首先,内核会给每个进程分配相等的初始时间片,然后每个进程轮番地执行相应的时间,当所有进程都处于时间片耗尽的状态时,内核会重新为每个进程计算并分配时间片,如此往复(1)。
但新的问题又出现了,进程拥有太多的资源,进程的创建、切换、销毁都会占用很长的时间,CPU虽然利用起来了,但如果进程过多,CPU会有很大的一部分被用来进行进程切换调度,如图1.3所示。

图1.3 CPU调度切换的成本
对于Linux操作系统来言,CPU对进程和线程的态度是一样的,如图1.3所示,如果系统的CPU数量过少,而进程/线程数量比较庞大,则相互切换的频率也就会很高,其中中间的切换成本越来越大。这一部分的性能消耗实际上是没有做在对程序有用的计算算力上,所以尽管线程看起来很美好,但实际上多线程开发设计会变得更加复杂,开发者要考虑很多同步竞争的问题,如锁、资源竞争、同步冲突等。