进程调度
1. 进程调度
时间片
一个操作系统中运行的进程数量远大于CPU核心的数量,为了并发(Concurrency)执行多个进程,操作系统需要将CPU资源轮流分配给进程使用。
CPU调度进程的模型可简化为下图。
操作系统会为就绪的进程维护一个任务队列,队列中的进程将轮流使用CPU资源,每个进程每次只能在CPU上运行一小段时间。为了公平地分配处理器时间,并确保每个任务都有机会执行,操作系统使用调度算法将处理器时间划分为固定长度的时间片。
操作系统的资源分配
通过使用时间片,操作系统可以实现多任务并发执行。每个任务在自己的时间片内运行,当时间片用完时,系统会重新调度其他任务继续执行。这种轮转的调度方式确保了任务的公平性,并避免了某个任务长时间独占处理器资源,导致其他任务无法得到执行的情况。
上下文切换
由于进程是轮流被调度的,所以操作系统必须知道从哪里加载任务,以及从哪里开始运行。当进程在CPU上运行时,这些信息保存在CPU的一组寄存器中,比如其中的程序计数器(Program Counter,PC)这个寄存器用于保存将执行的下一条指令的地址。这些信息称为CPU上下文。
上下文切换
上下文切换是指 操作系统保存当前任务的上下文,并加载下一个任务的上下文 的过程。上下文包括了任务的寄存器状态、程序计数器、内存映射、打开文件等与任务执行相关的信息。通过上下文切换,操作系统可以暂停当前任务的执行,并切换到其他任务继续执行。
2. 进程状态的转换
三态模型
进程的三态模型是指进程在操作系统中的三种基本状态:运行态(Running)、就绪态(Ready)和阻塞态(Blocked)。
三态模型
1. 运行态(Running):进程当前正在被CPU执行指令,处于活动状态。进程在运行态下使用CPU资源执行其指令流,并在时间片用完或者主动放弃CPU时可能会转换到其他状态。
2. 就绪态(Ready):进程已经满足了执行的前提条件,但由于CPU资源有限,它还未被分配到CPU上执行。进程在就绪态下等待调度器将其选中并分配CPU资源,以便进入运行态执行。
3. 阻塞态(Blocked):进程由于某些原因无法继续执行,需要等待某个事件的发生,例如等待I/O操作完成或等待某个资源的释放。在阻塞态下,进程被置于等待队列中,直到所需的事件发生,然后可能转换到就绪态或运行态。
- 就绪 ⇨ 运行:当调度器从就绪队列中选择一个进程,并将CPU资源分配给它时,进程从就绪态转换到运行态。
- 运行 ⇨ 就绪:当进程的时间片用完、主动放弃CPU资源或被更高优先级的进程抢占时,进程从运行态转换到就绪态。
- 运行 ⇨ 阻塞:当进程需要等待某个事件发生时,例如等待I/O操作完成,它会从运行态转换到阻塞态,并将CPU资源释放给其他进程。
- 阻塞 ⇨ 就绪:当被等待的事件发生后,进程从阻塞态转换到就绪态,重新加入就绪队列,等待调度器将其选中并分配CPU资源。
当我们在Linux操作系统上查询到进程的状态为 R
时,说明该进程处于就绪态或者运行态。而查询状态为 S
时,则处于阻塞态。
五态模型
五态模型在三态模型的基础上增加了新建态(New)和终止态(Terminated)。
五态模型
在三态模型的基础上,新增了两个状态:
4. 创建态(New):进程正在被创建,但尚未完全准备好运行。在创建态下,操作系统正在为进程分配必要的资源和数据结构。一旦创建完成,进程将转换到就绪态等待被调度。
5. 终止态(Terminated):进程已经完成了它的执行,或者由于某些原因被操作系统终止。在终止态下,进程释放占用的资源,并等待操作系统回收其相关的数据结构。
- 创建 ⇨ 就绪:当进程被创建并准备好运行时,它从创建态转换到就绪态,等待调度器将其选中并分配CPU资源。
- 运行 ⇨ 终止:当进程完成了它的执行或者被操作系统终止时,进程从运行态转换到终止态,释放占用的资源。
七态模型
七态模型在五态模型的基础上还引入了两个额外的状态挂起就绪态(Suspended Ready)和挂起阻塞态(Suspended Blocked)。
在之前Linux进程状态的例子中,使用 kill -SIGSTOP
命令向进程发送信号使其转换为 T
状态使其暂停,就属于挂起就绪态的一种。
七态模型
在五态模型的基础上,新增了两个状态:
6. 挂起就绪态(Suspended Ready):进程被挂起,暂时不参与调度和执行,但已准备好运行。
7. 挂起阻塞态(Suspended Blocked):进程被挂起,暂时不参与调度和执行,且处于阻塞状态。
在某些情况下,操作系统的负载管理机制可能会挂起一些进程,以便在系统资源紧张时为其他重要任务腾出空间。
在Linux中,当系统内存资源不足时,操作系统可以使用 Swap
来将部分内存中的进程数据写入到硬盘上的Swap分区或Swap文件中。这样可以释放内存空间,为其他进程提供更多的可用内存。
当一个进程被挂起时,可能会将其相关的数据写入到 Swap
中,以释放内存。这样进程的状态可以转换为挂起就绪态(Suspended Ready)或挂起阻塞态(Suspended Blocked)。在这种状态下,进程不占用实际的内存资源,而是保存在Swap中,以便在需要时进行恢复。
当操作系统决定重新调度挂起的进程时,它从Swap中读取进程的数据,将其恢复到内存中,并将其状态转换为就绪态(Ready)或阻塞态(Blocked),具体取决于进程在挂起之前的状态。