Author : Cyan_RA9
Source : 【卡码笔记】网站
Question : 进程有几种状态,它们之间是如何转换的?
【简要回答】
进程的五状态模型
- 创建态(New):
进程正在被创建,操作系统将根据系统资源的占用情况,为其分配内存、PID等资源,但尚未加入调度队列。 - 就绪态(Ready):
进程已获得除 CPU 外的所有资源,等待被调度程序选中,上处理器执行。 - 执行态(Running):
进程占用 CPU 执行指令,是唯一真正在运行的状态。 - 阻塞态(Blocked):
进程因等待外部事件(如 I/O 完成、信号量释放)暂停执行,主动让出 CPU。 - 终止态(Terminated):
进程执行完毕或异常退出(如Linux中向进程发送KILL信号),操作系统回收其资源并销毁进程控制块(PCB)。
“五状态模型”中的状态切换
- 创建态 → 就绪态:
- 原因:操作系统完成资源分配(内存、PID等),将进程加入就绪队列。
- 就绪态 → 执行态:
- 原因:调度程序根据当前调度算法(如时间片轮转、优先级调度)选中该进程并分配 CPU。
- 执行态 → 就绪态:
- 原因:当前正在执行的进程时间片耗尽或被更高优先级的进程抢占,进程重新回到就绪队列。
- 执行态 → 阻塞态:
- 原因:进程主动等待资源(如
read()请求磁盘 I/O)或事件(如sleep())。
- 原因:进程主动等待资源(如
- 阻塞态 → 就绪态:
- 原因:等待的资源空闲或事件完成(如 I/O 结束、信号量释放),进程可被调度,重新加入就绪队列中。
- 执行态 → 终止态:
- 原因:进程运行完毕正常退出(如
exit())或发生错误被强制终止(如kill -9)。
- 原因:进程运行完毕正常退出(如
【详细回答】
五状态模型
- 进程的五状态模型:
- 创建态(New)
- 基本概念:进程正在被创建,操作系统为其分配内存、PID 等基础资源,但尚未加入调度队列。
- 资源占用:已分配 PCB(进程控制块)和少量内存,未占用 CPU,可能还需要等待其他所需资源。
- 操作系统行为:初始化 PCB,加载程序代码到内存,完成资源分配后将其加入就绪队列。
- 就绪态(Ready)
- 基本概念:进程已获得除 CPU 外的所有资源,等待被调度程序选中执行,上处理器执行。
- 资源占用:占用内存、文件句柄等资源,未占用 CPU。
- 操作系统行为:维护就绪队列,通过调度算法(如时间片轮转、优先级)选择下一个运行进程。
- 执行态(Running)
- 基本概念:进程占用 CPU 执行指令,是唯一真正在运行的状态。
- 资源占用:占用 CPU、内存及其他运行所需的资源(如打开的文件)。
- 操作系统行为:处理时钟中断、系统调用,保存和恢复进程上下文。
- 阻塞态(Blocked)
- 基本概念:进程因等待外部事件(如 I/O 完成、信号量释放)主动让出 CPU。
- 资源占用:未占用CPU,可能还需要等待其他所需资源。
- 操作系统行为:将进程移入阻塞队列,监控等待事件的状态。
- 终止态(Terminated)
- 基本概念:进程执行完毕或异常退出(如Linux中向进程发送KILL信号,或Windows下在任务管理器中结束进程),操作系统回收其资源并销毁进程控制块(PCB)。
- 资源占用:释放所有资源(内存、文件、PID 等)。
- 操作系统行为:回收该进程拥有资源,销毁 PCB,并通知父进程(通过
wait()系统调用),更新进程状态表。
- 创建态(New)
- 五状态模型中的状态切换:
- 创建态 → 就绪态
- 触发条件:进程创建成功,操作系统完成资源分配(内存、PID、PCB 初始化)。
- 典型场景:用户执行命令(如
./a.out)或程序调用fork()创建子进程。
- 就绪态 → 执行态
- 触发条件:调度程序根据特定的进程调度算法(如时间片轮转、抢占式优先级调度)选中处于就绪态的进程并分配 CPU。
- 典型场景:就绪队列中的进程被调度程序选中,开始执行。
- 执行态 → 就绪态
- 触发条件:时间片耗尽或被更高优先级进程抢占。
- 典型场景:多任务操作系统中进程切换(如 Linux 的 CFS 调度器)。
- 执行态 → 阻塞态
- 触发条件:进程主动等待资源或事件(如
read()请求磁盘 I/O)。 - 典型场景:进程调用
sleep()暂停执行,或等待互斥锁释放。
- 触发条件:进程主动等待资源或事件(如
- 阻塞态 → 就绪态
- 触发条件:等待的事件完成(如 I/O 操作结束、信号量释放)。
- 典型场景:磁盘数据读取完成,唤醒等待该 I/O 的进程。
- 执行态 → 终止态
- 触发条件:进程正常退出(
exit())或被强制终止(如kill -9)。 - 典型场景:程序执行完毕或发生致命错误(如段错误)。
- 触发条件:进程正常退出(
- 创建态 → 就绪态
三状态模型
- 进程的三状态模型:(来自“五状态模型”)
- 就绪态(Ready)
- 执行态(Running)
- 阻塞态(Blocked)
- 三状态模型中的状态切换:
- 就绪态 → 执行态
- 触发条件:调度程序选中处于就绪态的进程,并为其分配 CPU 时间片。
- 典型场景:进程从就绪队列中被选中,开始运行。
- 执行态 → 就绪态
- 触发条件:时间片耗尽或被更高优先级进程抢占。
- 典型场景:多任务系统中的进程切换。
- 执行态 → 阻塞态
- 触发条件:进程主动请求资源(如 I/O 请求),因资源不可用而等待。
- 典型场景:调用
read()读取磁盘数据。
- 阻塞态 → 就绪态
- 触发条件:等待的事件完成(如 I/O 完成)。
- 典型场景:磁盘数据就绪,唤醒阻塞进程。
- 就绪态 → 执行态
七状态模型
- 进程的七状态模型:(相比“五状态模型”多了下面2种状态)
- 这两个状态的引入主要是为了解决内存资源不足的问题,通过将暂时不运行的进程从内存移到外存(交换区),从而释放内存空间。
- 就绪挂起态(Ready Suspended) :进程位于外存中,但已具备运行条件(只要调入内存即可执行)。
- 阻塞挂起态(Blocked Suspended) :进程位于外存中,并正在等待某个事件(如I/O完成)。
- 七状态模型中的状态切换:(相比“五状态模型”多了下面5种切换场景)
- 就绪态 → 就绪挂起态
- 触发条件:内存不足,操作系统主动换出进程以释放内存。
- 典型场景:系统高负载时,将低优先级就绪进程换出内存。
- 就绪挂起态 → 就绪态
- 触发条件:内存充足,操作系统将进程换入内存。
- 典型场景:用户手动恢复挂起的进程(如
fg命令)。
- 阻塞态 → 阻塞挂起态
- 触发条件:内存不足且进程等待的事件耗时较长。
- 典型场景:换出等待网络 I/O 或用户输入的进程。
- 阻塞挂起态 → 阻塞态
- 触发条件:内存充足且事件未完成,操作系统将进程换入内存继续等待。
- 典型场景:内存释放后恢复进程,但事件仍需等待(如用户输入未就绪)。
- 阻塞挂起态 → 就绪挂起态
- 触发条件:等待的事件完成,但内存仍然不足,无法换入内存。
- 典型场景:磁盘 I/O 完成,但系统仍处于高负载状态,进程保留在磁盘中等待调度。
- 就绪态 → 就绪挂起态
【知识拓展】
- 一图胜千言:
- 关于七状态模型的一些额外说明:
- 进程从阻塞挂起态,可以转换为阻塞态(内存充足但等待的事件仍未完成),也可以转换为就绪挂起态(事件完成但内存不足),还可以直接转换为就绪态(等待的事件完成且内存充足);
- 虽然多数情况下,对七状态模型的描述中没有“阻塞挂起态 → 就绪态”的直接转换,但需要知道这种情况是可以发生的:在 《Operating System Concepts》 一书中,Chapter 3.6.2 明确提到 "When an event for which a blocked suspended process has been waiting occurs, the process is moved to the ready-suspended state if memory is still not available, or to the ready state if memory is available."。
- 线程的状态:
- 内核级线程:(类似于进程的五状态模型,但状态转换的复杂度和资源管理开销更低)
① 创建态(New):线程正在创建,分配资源。
② 就绪态(Ready):线程准备好运行,等待 CPU。
③ 运行态(Running):线程占用 CPU 执行指令。
④ 阻塞态(Blocked):线程等待资源,主动让出 CPU。
⑤ 终止态(Terminated):线程执行完毕,资源回收。 - 用户级线程:(以Java语言为例)
① 新建(NEW):线程对象已创建但未启动。
② 可运行(RUNNABLE):线程已启动,可能在运行或等待 CPU。
③ 阻塞(BLOCKED):线程因锁竞争被阻塞。
④ 等待(WAITING):线程无限期等待信号。
⑤ 定时等待(TIMED_WAITING):线程在指定时间内等待。
⑥ 终止(TERMINATED):线程执行完毕或异常退出。
- 内核级线程:(类似于进程的五状态模型,但状态转换的复杂度和资源管理开销更低)