当前课程知识点:操作系统 > 第十一讲 进程和线程 > 11.3 进程状态 > 11.3 进程状态
接下来我们讨论进程的状态
进程的状态呢是指操作系统为了
维护进程执行的过程当中的
所有信息的变化
那它有必要知道进程
在执行过程当中会出现哪些状态
它会在什么情况下会发生变化
那这是呢我们对进程
在整个生命周期当中
它可能出现的一些事件的划分
这种划分呢在不同的
操作系统当中它会不一样
比如说在我们这里头
把它划分成创建
有可能你需要其中一个程序执行
那这个启动过程
就会导致一个新的进程的创建
那创建完了之后呢
它就会是程序进入执行的状态
这是第二个
它会占用CPU来执行
在执行的过程当中它可能会由于
等待某个资源或者
等待某个数据而进入等待状态
好那这个时候呢
就导致进程进行等待
好在执行的过程当中
还会有另外一种情况
你比如说
我一个优先级低的进程正在执行
这时候有一个高优先级的进程
有等待状态结束
就是它等待的条件已经成熟了
已经满足了
好那这时候它要马上开始投入运行
有可能我当前这个进程是会抢先
那这时候呢我这个
先进入就绪状态这个进程叫抢先
而当前正在执行这个进程呢
叫做被抢占
好那处于等待状态的进程呢
它会碰到被唤醒的情况
在外界条件满足的时候它会被唤醒
唤醒之后呢
又排到这个就绪队列里头
也就说它等待占用CPU来继续执行
那等最后回到CPU上执行
执行到最后的某种状态呢
整个程序的工作全部执行完
那就有可能进到进程结束的状态
那这时候到达结束
那整个呢这是我们在这里头
对进程的生命周期的一个划分
这种划分呢在不同系统里呢
会有一些变化
大致的情况呢基本上就是这几种
那我们具体来讨论一下
这些状态的变化
首先一个进程创建
要创建一个进程
实际上我们在前面说
每一个进程有一个进程控制块
那这些相关的它要占用内存
把代码和数据都拷进去
这些资源的准备过程
就对应到我们这里进程创建
那可能导致创建的事件呢
有这样几种
第一个系统初始化
初始化完成之后
我要创建第一个用户进程
那这是一种情况
然后在用户进程执行的过程当中
我可能会要执行某项功能
用户请求创建一个新的进程
那实际上这个请求过程呢
也会导致一个程序
我会执行创建进程的系统调用
这是我们操作系统对上
提供的创建进程的API
好创建好了这个进程之后呢
我们就会放到内核里的
就绪队列里头
这时候进程控制块呢
就排到这个就绪队列里头
好那等待CPU调度
那如果说这个处理机
没有其它进程运行
那我就会调度一个
新的进程来运行
这时候调度呢就会
导致我这个进程进入运行状态
那我如何来选择一个
就绪进程来运行
如果说你只有一个那我就选择它
如果有多个我怎么选择
那实际上这种选择的依据呢
就是我们后面会讲到的
处理机的调度算法
那不同的调度算法系统会体现出
不同样的进程执行的特征
好在执行的过程当中呢
有可能进程执行的
某一项条件不成立
需要等待的某个数据
或者说外部资源不足够
那这时候呢
我进程会进入等待状态
那这种等待状态呢
可能的原因是说
我等待的系统的服务
并没有马上完成
或者说我启动的某个操作
比如说我读写磁盘
那这个读的过程呢
它并不能在很短的时间里给出来
因为我指令执行的速度
是远高于我磁盘读写的速度了
好再有一个就是
我等待需要的数据没有到达
那这些都会导致
我进程进到等待状态
一旦这些等待事件出现之后
它就会回到这儿
那么在这中间呢还会再有一种情况
在这里呢等待事件的进入一定是我
正在运行这个进程
本身内部的原因所导致的
它不是由于外部原因
所导致它进入等待状态的
好在执行的过程当中呢
还有一种可能的变化
就是我正在运行的进程被抢占
那这种情况呢会出现在
我有高优先级的进程变成就绪
它需要马上投入运行
那会把我正在运行的这个进程呢
变成就绪然后让它运行
第二种情况呢是说
我们在操作系统里头它的调度算法
为每个进程分配了
它可以执行的最长时间
如果你分配的这个时间片用完了
那这时候呢
系统
操作系统内核会强制把这个进程呢
抢先让下一个进程投入运行
那这是呢时间片在这里起到的作用
好那这个地方呢是说
我在什么情况会回到就绪状态
那就是说我进程被唤醒
那唤醒的可能条件呢是
我们刚才进入等待的
那几个条件的反过来
我等待的资源满足了
我等待的事件出现了
那都会出现这种情况
而和这个等待进入相反
唤醒的条件呢
一定是被其别的进程或者
操作系统唤醒
它不会是由于自身的原因直接回去
那这是呢在这里唤醒的时候的情况
那在执行的过程当中
还有一种情况呢是说
我在执行到整个进程
执行结束那我要退出
这是要干什么呢
要把进程执行所占用的
所有资源还给操作系统
以便于它能把它分配给
新的进程使用
如果没有这个过程的话
那分配出的资源就会丢掉了
那在这个过程当中呢
结束呢有这样几种情况
这是我们希望的正常退出
那在正常退出之外呢
还有一些意外的原因
你比如说出现错误
错误呢分成一般的错误
我可以做收尾的
那就是错误退出
有一些错误是没有任何理由
它直接就跑不动了
那这就是致命性错误
那这时候呢你可能这个收尾工作
就做的不是很完善
还有一种情况就是
你在执行过程当中
其他的进程认为你有问题
那可能这种认为也不一定是正确的
好它强制把这进程杀掉
那这是几种我们
从运行到退出的情况
那有了这些说明之后呢
我们关于进程的状态的变化情况呢
就有一个基本的了解
那下面呢我们通过一个小例子
来说明进程状态的变化情况
那在这里头呢我们假定
我写了一个小程序
这个小程序呢进来之后
执行的主要操作就是
延时两秒然后结束
那在这个小程序呢
它会什么样状态
首先我启动这个小程序的时候
它会有创建
创建呢去分配
这个进程执行所需要的资源
你比如说内存
好相关的数据结构初始化
完成之后那这就进入就绪状态
进入就绪状态呢是说
我把这个进程所创建的
包括进程控制块
挂到就绪队列里头去
好然后在就绪队列里头等待
占用CPU的进程结束退出
或者说被抢先
好然后这时候呢
在CPU的调度下它就可以
从这儿进到占用CPU来开始执行
在执行的过程当中会执行到
你的sleep这个系统调用
这个调用呢它设置好定时器
那这时候呢它就没事干了
因为我们延时两秒
中间这两秒它是做不了任何事情的
好在这两秒钟的时候呢
那它就会进到等待状态
那等待状态结束呢
是说我这边的在内核里
它的sleep操作会设定时器
定时器在两秒钟到了之后呢
它会给系统一个中断
好这个中断呢会导致系统说
这个中断是原因是什么
最后找到这个进程
好通知它
它可以进到就绪状态
好那这时候操作系统内核代码
会把这个处于等待状态的进程呢
放到就绪队列里头去
并且把它的等待事件设置为出现
好然后等待CPU调度
就处于就绪状态
好等到它可以占用CPU来运行的时候
那又进到运行状态
那到这儿呢我们这个基本的操作
就执行的差不多了
接下来是说它要退出
然后把它所占用资源全部还回去
那我这个进程的整个生命周期呢
就全部完成了
那我们所有的程序在执行过程当中呢
我们操作系统需要对这个过程
进行全面准确的把握
只有这样的话我才可以知道
我这个进程执行的情况
那么在这个里头呢
我们还会涉及到一个问题是说
我一个进程进入等待
或者说被抢先或者说结束
我都需要找另一个进程来继续运行
那这时候就有一个进程的切换
那这是我们在内存当中
当前正在交替运行的N个进程
那这个切换的过程是怎么进行的呢
我们在这里头进程一进程二
我们假定有两个进程
好首先呢假定跟我刚才例子一样
它进到这里头执行sleep
这时候呢会导致进入内核
这仍然算是这个进程执行的时间
好然后呢
内核里头会调用函数设置定时器
那这是这边设备
这个设备呢可以和
我们CPU呢同时运行
这是并行的好
设置好了定时器之后呢
那我这个程序就走不下去了
那它就会执行调度
这个调度呢会把
当前的进程的
占用的寄存器的状态呢
都保存到进程控制块里头
然后它这时候切换到第二个进程
这是从就绪队列里找出来的
然后让第二个进程呢开始运行
那在这个运行的过程当中
它可能会是说
你的这个定时器的时间到了
这个时候定时器呢会产生一个中断
这个中断呢会在这里做响应
这个响应的操作是
让这个进程暂停下来
并且保护进程二的现场
恢复进程一的现场
恢复完毕之后让进程一继续执行
那么等到这个进程执行结束呢
它就再回到操作系统
这相当于我们最后那个
结束那个进程
好那实际上我们在
这个整个操作系统
在掌控内部正在运行
所有进程运行过程呢
就是从一个切到另一个
再从另一个再切回来
周而复始的这样来切换
那这是进程切换的情况
-0.1 Piazza讨论区
--html
-0.2 在线实验平台
--实验平台使用帮助
--平台使用帮助
-0.2在线实验平台
--Raw HTML
-1.1 课程概述
--视频
-第一讲 操作系统概述--练习
-1.2 教学安排
--视频
-1.3 什么是操作系统
--Video
-1.4 为什么学习操作系统,如何学习操作系统
--Video
-1.5 操作系统实例
--视频
-1.6 操作系统的演变
--视频
-1.7 操作系统结构
--视频
-2.1 前言和国内外现状
-2.2 OS实验目标
-2.3 8个OS实验概述
-2.4 实验环境搭建
-2.5 x86-32硬件介绍
-2.6 ucore部分编程技巧
-2.7 演示实验操作过程
--Q6
--Q7
--Q10
-3.1 BIOS
--3.1 BIOS
-3.2 系统启动流程
-3.3 中断、异常和系统调用比较
-第三讲 启动、中断、异常和系统调用--3.3 中断、异常和系统调用比较
-3.4 系统调用
--3.4 系统调用
-第三讲 启动、中断、异常和系统调用--3.4 系统调用
-3.5 系统调用示例
-3.6 ucore+系统调用代码
-4.1 启动顺序
--4.1 启动顺序
-4.2 C函数调用的实现
-4.3 GCC内联汇编
-4.4 x86中断处理过程
-4.5 练习一
--4.5 练习一
-4.6 练习二
--4.6 练习二
-4.7 练习三
--4.7 练习三
-4.8 练习四 练习五
-4.9 练习六
--4.9 练习六
-5.1 计算机体系结构和内存层次
-5.2 地址空间和地址生成
-5.3 连续内存分配
-5.4 碎片整理
--5.4 碎片整理
-5.5 伙伴系统
--5.5 伙伴系统
-第五讲 物理内存管理: 连续内存分配--5.6 练习
-6.1 非连续内存分配的需求背景
-6.2 段式存储管理
-- 6.2 段式存储管理
-6.3 页式存储管理
-6.4 页表概述
--6.4 页表概述
-6.5 快表和多级页表
-6.6 反置页表
--6.6 反置页表
-6.7 段页式存储管理
-第六讲 物理内存管理: 非连续内存分配--6.8 练习
-7.1 了解x86保护模式中的特权级
-第七讲 实验二 物理内存管理--7.1 了解x86保护模式中的特权级
-7.2 了解特权级切换过程
-第七讲 实验二 物理内存管理--7.2 了解特权级切换过程
-7.3 了解段/页表
-第七讲 实验二 物理内存管理--7.3 了解段/页表
-7.4 了解UCORE建立段/页表
-第七讲 实验二 物理内存管理--7.4 了解UCORE建立段/页表
-7.5 演示lab2实验环节
-8.1 虚拟存储的需求背景
-8.2 覆盖和交换
-8.3 局部性原理
-8.4 虚拟存储概念
-8.5 虚拟页式存储
-8.6 缺页异常
--8.6 缺页异常
-9.1 页面置换算法的概念
-9.2 最优算法、先进先出算法和最近最久未使用算法
-第九讲 页面置换算法--9.2 最优算法、先进先出算法和最近最久未使用算法
-9.3 时钟置换算法和最不常用算法
-第九讲 页面置换算法--9.3 时钟置换算法和最不常用算法
-9.4 Belady现象和局部置换算法比较
-第九讲 页面置换算法--9.4 Belady现象和局部置换算法比较
-9.5 工作集置换算法
-第九讲 页面置换算法--9.5 工作集置换算法
-9.6 缺页率置换算法
-第九讲 页面置换算法--9.6 缺页率置换算法
-9.7 抖动和负载控制
-10.1 实验目标:虚存管理
-第十讲 实验三 虚拟内存管理--10.1 实验目标:虚存管理
-10.2 回顾历史和了解当下
-第十讲 实验三 虚拟内存管理--10.2 回顾历史和了解当下
-10.3 处理流程、关键数据结构和功能
-第十讲 实验三 虚拟内存管理--10.3 处理流程、关键数据结构和功能
-10.4 页访问异常
-第十讲 实验三 虚拟内存管理--10.4 页访问异常
-10.5 页换入换出机制
-第十讲 实验三 虚拟内存管理--10.5 页换入换出机制
-11.1 进程的概念
-第十一讲 进程和线程--11.1 进程的概念
-11.2 进程控制块
-第十一讲 进程和线程--11.2 进程控制块
-11.3 进程状态
-第十一讲 进程和线程--11.3 进程状态
-11.4 三状态进程模型
-11.5 挂起进程模型
-第十一讲 进程和线程--11.5 挂起进程模型
-11.6 线程的概念
-第十一讲 进程和线程--11.6 线程的概念
-11.7 用户线程
-第十一讲 进程和线程--11.7 用户线程
-11.8 内核线程
-第十一讲 进程和线程--11.8 内核线程
-12.1 进程切换
-第十二讲 进程控制--12.1 进程切换
-12.2 进程创建
-第十二讲 进程控制--12.2 进程创建
-12.3 进程加载
-第十二讲 进程控制--12.3 进程加载
-12.4 进程等待与退出
-第十二讲 进程控制--12.4 进程等待与退出
-13.1 总体介绍
-13.2 关键数据结构
-13.3 执行流程
-13.4 实际操作
-14.1 总体介绍
-14.2 进程的内存布局
-14.3 执行ELF格式的二进制代码-do_execve的实现
--14.3 执行ELF格式的二进制代码-do_execve的实现
-14.4 执行ELF格式的二进制代码-load_icode的实现
--14.4 执行ELF格式的二进制代码-load_icode的实现
-14.5 进程复制
-14.6 内存管理的copy-on-write机制
-15.1 处理机调度概念
-第十五讲 处理机调度--15.1 处理机调度概念
-15.2 调度准则
-15.3 先来先服务、短进程优先和最高响应比优先调度算法
--15.3 先来先服务、短进程优先和最高响应比优先调度算法
-第十五讲 处理机调度--15.3 先来先服务、短进程优先和最高响应比优先调度算法
-15.4 时间片轮转、多级反馈队列、公平共享调度算法和ucore调度框架
--15.4 时间片轮转、多级反馈队列、公平共享调度算法和ucore调度框架
-第十五讲 处理机调度--15.4 时间片轮转、多级反馈队列、公平共享调度算法和uc
-15.5 实时调度和多处理器调度
-第十五讲 处理机调度--15.5 实时调度和多处理器调度
-15.6 优先级反置
-第十五讲 处理机调度--15.6 优先级反置
-16.1 总体介绍和调度过程
-16.2 调度算法支撑框架
-16.3 时间片轮转调度算法
-16.4 Stride调度算法
-17.1 背景
--17.1 背景
-17.2 现实生活中的同步问题
-第十七讲 同步互斥--17.2 现实生活中的同步问题
-17.3 临界区和禁用硬件中断同步方法
-第十七讲 同步互斥--17.3 临界区和禁用硬件中断同步方法
-17.4 基于软件的同步方法
-第十七讲 同步互斥--17.4 基于软件的同步方法
-17.5 高级抽象的同步方法
-第十七讲 同步互斥--17.5 高级抽象的同步方法
-18.1 信号量
--18.1 信号量
-第十八讲 信号量与管程--18.1 信号量
-18.2 信号量使用
-第十八讲 信号量与管程--18.2 信号量使用
-18.3 管程
--18.3 管程
-第十八讲 信号量与管程--18.3 管程
-18.4 哲学家就餐问题
-18.5 读者-写者问题
-19.1 总体介绍
-19.2 底层支撑
-第十九讲 实验七 同步互斥--19.2 底层支撑
-19.3 信号量设计实现
-第十九讲 实验七 同步互斥--19.3 信号量设计实现
-19.4 管程和条件变量设计实现
-第十九讲 实验七 同步互斥--19.4 管程和条件变量设计实现
-19.5 哲学家就餐问题
-20.1 死锁概念
-第二十讲 死锁和进程通信--20.1 死锁概念
-20.2 死锁处理方法
-第二十讲 死锁和进程通信--20.2 死锁处理方法
-20.3 银行家算法
-第二十讲 死锁和进程通信--20.3 银行家算法
-20.4 死锁检测
-第二十讲 死锁和进程通信--20.4 死锁检测
-20.5 进程通信概念
-第二十讲 死锁和进程通信--20.5 进程通信概念
-20.6 信号和管道
-第二十讲 死锁和进程通信--20.6 信号和管道
-20.7 消息队列和共享内存
-第二十讲 死锁和进程通信--20.7 消息队列和共享内存
-21.1 文件系统和文件
-第二十一讲 文件系统--21.1 文件系统和文件
-21.2 文件描述符
-第二十一讲 文件系统--21.2 文件描述符
-21.3 目录、文件别名和文件系统种类
-第二十一讲 文件系统--21.3 目录、文件别名和文件系统种类
-21.4 虚拟文件系统
-第二十一讲 文件系统--21.4 虚拟文件系统
-21.5 文件缓存和打开文件
-第二十一讲 文件系统--21.5 文件缓存和打开文件
-21.6 文件分配
-第二十一讲 文件系统--21.6 文件分配
-21.7 空闲空间管理和冗余磁盘阵列RAID
-第二十一讲 文件系统--21.7 空闲空间管理和冗余磁盘阵列RAID
-22.1 总体介绍
-第二十二讲 实验八 文件系统--22.1 总体介绍
-22.2 ucore 文件系统架构
-第二十二讲 实验八 文件系统--22.2 ucore 文件系统架构
-22.3 Simple File System分析
-第二十二讲 实验八 文件系统--22.3 Simple File System分析
-22.4 Virtual File System分析
-第二十二讲 实验八 文件系统--22.4 Virtual File System分
-22.5 I/O设备接口分析
-第二十二讲 实验八 文件系统--22.5 I/O设备接口分析
-22.6 执行流程分析
-23.1 I/O特点
--视频
-第二十三讲 I/O子系统--23.1 I/O特点
-23.2 I/O结构
--816C80A0F5E3B8809C33DC5901307461
-第二十三讲 I/O子系统--23.2 I/O结构
-23.3 I/O数据传输
--C58221E14388B9DB9C33DC5901307461
-第二十三讲 I/O子系统--23.3 I/O数据传输
-23.4 磁盘调度
--567A3F1FCBFB3F4C9C33DC5901307461
-第二十三讲 I/O子系统--23.4 磁盘调度
-23.5 磁盘缓存
--C327536B80D25CE79C33DC5901307461
-第二十三讲 I/O子系统--23.5 磁盘缓存
-html
--html