【操作系统】考研408操作系统核心考点:进程控制机制与原语实现深度解析​

(进程控制)

导读大家好,很高兴又和大家见面啦!!!

在上一篇内容中,我们共同探讨了进程的状态转换与组织方式。进程在其生命周期中会经历创建态、就绪态、运行态、阻塞态和终止态这五种状态的动态变迁,形成一个完整的生命周期循环。

理解进程状态转换的关键在于掌握三种基本状态间的转换规律:

从就绪态到运行态通过进程调度实现从运行态到就绪态常因时间片耗尽从运行态到阻塞态多因资源请求或事件等待从阻塞态到就绪态则发生在等待事件完成时这些转换构成了进程并发执行的基础。

操作系统通过进程控制块(PCB) 来记录每个进程的状态信息,并采用链接方式(如就绪队列、阻塞队列)或索引方式来组织这些PCB,确保系统能够高效地进行进程调度和资源管理。

理解了进程状态的“是什么”和“为什么”后,我们很自然会问:

操作系统是如何精准控制这些状态转换的? 进程是如何被创建、终止和调度的? 这些状态转换背后需要怎样的机制来保障其可靠性和一致性?

现在,就让我们带着这些问题,一起深入探讨进程控制的具体实现机制,揭开操作系统如何有效管理进程生命周期的神秘面纱。

一、定义进程控制 的主要功能是对系统中的所有进程实施有效的管理,它具有创建新进程、撤销已有进程、实现进程状态转换等功能。

简单来说,进程控制就是用来实现进程的状态转换。

代码语言:javascript复制graph LR

a[创建态]--->b[就绪态]--->c[运行态]--->d[终止态]

c--->e[阻塞态]--->b

c--->b一个进程从创建态转换到就绪态的过程就是创建一个新进程的过程;

一个进程从运行态转换到终止态的过程就是撤销已有进程的过程;

一个进程在运行过程中的状态转换就是就绪态、运行态以及阻塞态这三种基本状态之间的转换;

二、进程控制的实现而要实现这一进程控制的方式,就是通过原语。在之前的内容中我们有介绍过原语:

原语是操作系统底层具有以下特点的公用小程序:

处于操作系统的底层,是最接近硬件的部分这些程序的运行具有原子性,其操作只能一气呵成这些程序的运行时间都较短,而且调用频繁所谓的原子性指的是:一个操作或一系列操作被视为一个不可分割的整体。它们要么​​全部成功执行​​,要么​​完全不执行​​,不会出现“执行了一半”的中间状态。

2.1 使用原语的原因 为什么需要通过原语来实现进程控制呢?

这里我们以链接方式的进程组织形式进行说明:

代码语言:javascript复制graph LR

a[执行指针]--->PCB1

b[就绪指针]--->PCB2--->PCB3--->PCB4

c[阻塞指针]--->PCB5--->PCB6--->PCB7在操作系统中,进程会根据自己此时所处的状态而进入相应的队列中,而判断进程相应状态的方式,我们可以通过变量 state 来实现,如:

state == 1 表示该进程处于运行态state == 2 表示该进程处于就绪态state == 3 表示该进程处于阻塞态那么一个进程要完成状态的转换就需要执行两步操作:

将该进程的状态变量 state 更改为相应的状态值将该进程排入相应的队列中那么我们设想一下如果进程的状态转换不具备原子性,那么就会出现下面这种情况:

当 PCB1 的 CPU 时间片使用完后,其状态需要从运行态转换到就绪态。在整个转换的过程中,操作系统会执行以下指令:

将状态变量 state = 1 更改为 state == 2将 PCB1 排入就绪队列代码语言:javascript复制graph LR

a[执行指针]

b[就绪指针]--->PCB2[PCB2
state = 1]--->PCB3[PCB3
state = 2]--->PCB4[PCB4
state = 2]--->PCB1[PCB1
state = 2]

c[阻塞指针]--->PCB5[PCB5
state = 3]--->PCB6[PCB6
state = 3]--->PCB7[PCB7
state = 3]

classDef red fill: #ff9999, color: #000, stroke: #ff0000, stroke-width: 2px

class PCB1 red但是,在执行的过程中,在完成了状态变量的修改后,操作系统接收到了来自外部的中断指令,此时就无法执行第二步操作。

代码语言:javascript复制graph LR

a[执行指针]--->PCB1[PCB1
state = 2]

b[就绪指针]--->PCB2[PCB2
state = 2]--->PCB3[PCB3
state = 2]--->PCB4[PCB4
state = 2]

c[阻塞指针]--->PCB5[PCB5
state = 3]--->PCB6[PCB6
state = 3]--->PCB7[PCB7
state = 3]

classDef red fill: #ff9999, color: #000, stroke: #ff0000, stroke-width: 2px

class PCB1 red这就导致了上图所示的情况—— PCB1 始终保持着占用 CPU 无法进行解除。

为了避免这种情况的发生,我们就需要确保状态转换操作一气呵成,因此必须使用原语来实现状态转换操作。

那么现在问题来了,原语是如何实现的将操作一气呵成呢?

2.2 关中断与开中断在操作系统中存在着两条特权指令——关中断与开中断。

这两条指令的作用分别为:

关中断——使 CPU ​​暂时不响应​​(或忽略)可屏蔽的中断请求开中断——使 CPU ​​恢复响应​​可屏蔽中断请求这里我们通过一个简单的例子进行说明:

经过前面的学习,我们知道,所有的程序都是由一条条的指令构成,而这些指令会在运行时,被存储到内存块中,逐个执行;并且每执行完一条指令,都需要检测一下中断信号;

代码语言:javascript复制graph LR

subgraph 内存块

a[...]

b[指令1]

close[关中断]

c[指令2]

d[指令3]

open[开中断]

e[指令4]

f[...]

end

g[中断信号]--->c上图所示的就是在操作系统的内核中执行的一个程序。当这个程序正常执行时,其执行的顺序为:

指令1--->关中断--->指令2--->指令3--->开中断--->指令4从图中我们可以看到,在执行完关中断后,执行指令2之前存在一条中断信号,如果在正常的执行逻辑下,CPU会执行以下操作:

检测到中断信号处理中断信号继续回到发生中断的点,继续向后执行但是,在检测到该中断信号之前,CPU执行了关中断指令,这时 CPU 会直接忽略该信号,而继续往下执行,并且在执行开中断之前,会屏蔽所有的可屏蔽中断请求;

当 CPU 执行了开中断之后,会重新开始进行中断信号的检测,继续回到 每执行一条指令,就检测一次中断信号 的状态;

正是因为这两条特权指令,这就确保了这两条指令中间所有指令的原子性,就比如上图中的指令2和指令3;

下面我们需要思考一个问题——为什么开中断与关中断属于特权指令?

这里咱们先卖个关子,具体的内容我们留到下一篇中再详细的进行探讨。

结语今天的内容到这里就全部结束了。通过今天的学习,我们深入理解了​​进程控制​​的核心机制。

进程控制作为操作系统对进程实施有效管理的关键功能,通过创建新进程、撤销已有进程以及实现进程状态转换等功能,确保了系统能够高效地进行多任务并发处理。我们重点探讨了进程控制的核心实现方式——​​原语​​。

原语作为操作系统底层具有原子性的公用小程序,通过​​关中断​​和​​开中断​​这两条特权指令,确保了进程状态转换操作的完整性和一致性。这种"一气呵成"的执行特性,有效避免了因中断导致的进程状态不一致问题,为系统的稳定运行提供了坚实保障。

在接下来的内容中,我们将继续深入探讨具体的进程控制原语,了解操作系统是如何通过不同的原语来实现精确的进程管理。

互动与分享

点赞👍 - 您的认可是我持续创作的最大动力

收藏⭐ - 方便随时回顾这些重要的基础概念

转发↗️ - 分享给更多可能需要的朋友

评论💬 - 欢迎留下您的宝贵意见或想讨论的话题

感谢您的耐心阅读! 关注博主,不错过更多技术干货。我们下一篇再见!


什么是电视机消磁电阻?
探讨城市交通:为什么会导致堵车现象频发?