操作系统课堂笔记三-进程线程模型
文章目录
进程线程模型
进程模型
进程概述
- 多到程序设计技术: 允许多个程序同时进入内存并运行
- 并发环境: 一段时间间隔内, 但处理器中有两个或者两个以上的程序同时处于开始运行且尚未结束的状态, 且是无序状态
- 进程的定义
- 进程是具有独立功能的程序, 关于某个数据集合上的运行活动, 是操作系统进行资源分配和CPU调度的独立单位
- 是程序一次的执行过程
- 是正在运行程序的抽象
- 将一个cpu虚拟成多个(操作系统虚拟的特征)
- 操作系统以进程为单位进行资源分配: 内存, 文件
- 进程具有独立地址空间
- 调度: 操作系统将CPU控制权交给某一个进程
进程控制块PCB
- 别名: 进程描述符, 进程属性
- 作用
- 操作系统用于管理控制进程的一个数据结构
- 记录了进程的各种属性,描述出进程的运动变化过程(进程的进度)
- PCB是操作系统感知进程存在的唯一标志
- PCB和进程是一对一的关系
- 进程表: 每个进程的PCB关系表, 放在内存的固定区域, 大小是固定的(说明操作系统有最高并发度)
PCB结构
- 进程描述信息
- 进程唯一标识(ID)
- 进程名
- 用户标识(user_id)
- 进程组关系
- 进程控制信息
- 当前状态
- 优先级
- 代码执行入口地址
- 程序磁盘地址
- 运行统计信息(运行时间, 页面调度)
- 进程间同步和通信
- 进程队列和指针
- 进程消息队列指针
- 资源使用情况
- 虚拟地址空间状况
- 打开文件列表
- CPU现场
- 当进程停止运行, 要保存现场, 就会保存一些寄存器的值(PC, PSW, 通用寄存器, 栈指针等)
- 指向该进程页表的指针
进程状态
- 运行态: 占CPU,已经在CPU上运行
- 就绪态: 具备了运行的条件, 由于没有空闲的CPU所以暂时无法运行
- 等待态: 因为等待某一事件而暂时不能运行, 如: 去磁盘读数据
- 其他说法: 阻塞态 封锁态 睡眠态
状态模型转换
- 就绪->运行: CPU调度程序选中(获取CPU资源)
- 运行->就绪
- 时间片用完了
- 某个高优先级进程进入就绪态, 抢占了该正在执行的进程的资源, 被抢占进程进入就绪态
- 运行->等待
- 请求操作系统服务
- 需要某个资源, 但是不能立刻被使用
- 等待IO的结果
- 等另一个进程发消息
- 等待->就绪: 等待中的进程拿到了等待的资源, 立刻切换到就绪状态
进程其他状态
- 创建
- 已完成创建一进程必要的工作 -PID PCB
- 尚未同意执行该进程 -资源有限
- 终止
- 进程运行结束了
- 操作系统可以做一些数据统计工作
- 最后操作系统资源回收
- 挂起
- 用于调节负载
- 进程不占用内存空间, 其进程映像交接到磁盘上
- 挂起的进程从磁盘load出来的过程叫做**
进程状态总结
- 其实就是理解三状态模型, 五状态模型和七状态模型就行, 然后每个状态之间转换的原因指导一下。
- 我们看一下七状态模型示意图, 转自这里
- 其中阻塞状态->就绪挂起能直接转换, 是因为当阻塞->阻塞挂起的同时, 等待事件正好到达了
- 运行->就绪挂起 : 下CPU时候直接进入就绪挂起队列
进程队列
- 操作系统为每一类进程创建一个或多个队列
- 队列元素为PCB
- 伴随进程状态的改变, PCB从一个队列进入另一个队列
- 下面简单看下一个五状态进程模型的队列模型,转自这里
进程控制
- 完成进程之间各种状态的转换, 通过一系列原语完成
- 原语: 原语的意思是原子性操作
- 进程创建,撤销, 阻塞, 唤醒,挂起, **, 改变进程优先级原语等
- 进程的创建
- 分配唯一标识, 空的PCB
- 为进程分配地址空间
- 初始化进程控制块, 填写相应内容
- 设置相应队列指针(比如进入就绪队列, 指针指向就绪队列)
- 进程撤销
- 资源回收, 关闭文件, 网络断开等
- 撤销分配的PCB
- 进程阻塞
- 运行状态的程序等待一些事件 如: 等待输入
- 自身调用阻塞原语实现
Unix中的几个进程控制操作
- unix中主要通过fork, wait, exec和exit来实现
- unix fork的实现细节看另一篇文章unix中fork的实现
进程分类
- 按照用户和系统分类
- 用户进程
- 系统进程
- 按照前后台分类
- 前台进程
- 后台进程: 比如我们操作系统初始化时候邮件进程等等
- 按照操作类型分类
- CPU密集型进程: 比如我们玩游戏, 需要大量的计算
- I/O密集型进程: 我们程序需要大量读盘
进程映像
- 相当于某一瞬间的进程快照, 映像中有的一些东西如下:
- 用户相关: 进程地址空间(包括代码段, 数据段, 堆栈, 共享库…)
- 寄存器相关: 程序计数器, 指令寄存器, 程序状态字寄存器, 栈指针, 通用寄存器等的值
- 内核相关: PCB和各种资源数据结构
- 动态部分: 内核栈(不同进程进入内核后使用不同的内核栈)
上下文切换
- 概念: 将CPU硬件状态从一个进程切换到另一个进程的过程叫做上下文切换
- 过程
- 程序运行时, 硬件状态都保存在CPU的寄存器(PC, PSW, 栈指针, 通用寄存器, 其他控制寄存器)
- 程序停止时, 将CPU中的一些寄存器信息保存到PCB中, 当程序需要一个新值上CPU时, 程序会将PCB中相关信息推向CPU的寄存器.
线程模型
线程的定义
- 我们知道,进程是资源的拥有者,CPU的调度单位
- 线程继承了调度CPU的功能, 资源还是由进程来管理
- 所以, 线程是进程中的运行实体, 又称作轻量级进程
线程的属性
- 唯一的标识 id
- 有状态的转换(能上下CPU)
- 线程不运行需要保存上下文环境(也需要一些寄存器)
- 有自己的栈指针
- 同一个进程中的所有线程是共享该进程中的资源和地址空间的(所以为通信和资源共享带来了便利)
- 线程也能创建撤销另一个线程
线程机制的实现
-
用户级线程: 所有的线程都是由一个线程表的数据结构来管理, 对于内核来说是无感知的, 内核管理的还是进程.因此, 线程的切换不需要操作系统的干预
- POSIX: Portable Operating System Interface 多线程编程接口
- yield函数: python里面也经常用到, 表示线程自动让出cpu, 因为线程没有时钟中断的概念, 所以需要自动让出cpu
- Linux系统
-
核心级线程: 内核管理所有的线程, 并向应用程序提供API接口, 内核维护进程和线程切换的上下文 : Window
- 在用户空间和内核空间一一对应一份线程, 内核线程上CPU就是用户空间线程上CPU, 核心技术就是多路复用
-
混合-两种方法: 创建在用户空间,调度在内核空间 Solaris