Version: Next
进程定义
程序:就是一个指令序列
- 早期计算机只支持 单道程序
- 引入 多道程序 后:内存中出现
多个程序段
、多个数据段
- 需要在他们之间找到正确的地址进行切换
- IO 系统也要响应进行切换以实现被多个程序共用
- 为了操作系统管理,完成各程序并发执行,引入了
进程
、进程实体
的概念进程控制块
- 系统为每个运行的程序配置一个数据结构,称为
进程控制块 PCB
(Process Control Block),用来描述进程的各种信息进程实体
- PCB、程序段、数据段 三部分构成了
进程实体
也称进程映像
,简称进程
- 所谓创建进程:实质上是创建进程实体中的 PCB
- 所谓撤销进程:实质上是撤销进程实体中的 PCB
PCB 是进程存在的唯一标志
等价定义
从不同的角度,进程可以有不同的定义,他们都强调
动态性
,比较传统典型的定义有:
- 进程是程序的一次执行过程
- 进程是一个程序及其数据在处理机上顺序执行时所发生的活动
- 进程是具有独立功能的程序在数据集合上运行的过程,它是系统进行资源分配和调度的一个独立单位
引入进程实体的概念后,可把进程定义为:
进程
是进程实体
的运行过程,是系统进行资源分配
和调度
的一个独立单位
注意
严格来说,进程实体和进程并不一样
- 进程实体是静态的,进程则是动态的
- 不过除非明确区分,一般情况下认为进程实体就是进程
- 因此一般可以说,"进程由程序段、数据段、PCB 三部分组成"
进程控制块 —— PCB
操作系统通过 PCB 来管理进程,因此 PCB 中应该包含操作系统对其进行管理所需的各种信息
- PCB
- 进程描述信息
- 进程标识符 PID
- 用户标识符 UID
- 进程控制和管理信息
- 进城当前状态
- 进程优先级
- 资源分配清单
- 程序段指针
- 数据段指针
- 键盘
- 鼠标
- ..
- 处理机相关信息
- 各种寄存器
进程的组织
随着系统中 PCB 数目的激增,应当用适当的方式把这些 PCB 组织起来
- 进程的组成:讨论一个银城内部由哪些部分构成
- 进程的组织:讨论多个进程之间的组织问题
- 链接方式
- 按照进程状态将 PCB 分为多个
队列
- 操作系统持有指向各个队列的指针
- 索引方式
- 根据进程状态的不同,建立几张索引表
- 操作系统持有指向各个索引表的指针
链接方式
- 执行指针:指向当前处于运行状态的进程
- 就绪表指针:指向当前处于就绪状态的进程,各个 PCB 通过链表形成一个队列,通常会把优先级高的进程放在队头
- 阻塞表指针:指向当前处于阻塞态的进程,很多操作系统还会根据阻塞原因不同,再分为多个阻塞队列
索引方式
- 执行指针:指向当前处于运行状态的进程
- 就绪表指针:指向当前处于就绪状态的进程,各个 PCB 的地址存储在就绪索引表中
- 阻塞表指针:指向当前处于阻塞态的进程,各个 PCB 的地址存储在阻塞索引表中
进程的特征
进程和程序是两个截然不同的概念
相比于程序,进城拥有以下特征:
- 动态性:进程是程序的一次执行过程,是
动态
的产生、变化和消亡的- 并发性:内存中有多个进程实体、各进程可并发执行
- 独立性:进程是能独立运行、独立获得资源、独立接收调度的基本单位。进程是资源分配、接收调度的基本单位
- 异步性:各进程按各自独立的、
不可预知
的速度向前推进,操作系统要提供 ”进程同步机制“ 来解决异步问题
- 结构性:每个进程都会配置一个 PCB ,结构上看,进程由 程序段、数据段、PCB 组成
进程的状态与转换
进程状态
状态
- 运行状态
- 就绪状态
- 阻塞状态
- 创建状态
- 终止状态
其中:
运行状态
、就绪状
态、阻塞状
态 称为三种基本状态
- 运行态(Running):占有 CPU,并在 CPU 上运行
- 就绪态 (Ready):已经具备运行条件,但由于没有空闲的 CPU,而暂时不能运行
- 阻塞态 / 等待态(Blocking / Waiting):因等待某一事件而暂时不能运行
创建、终止状态,主要处理 PCB、程序段、数据段 的开辟与销毁
进程状态转换
进程状态间的转换:
- 就绪态 → 运行态
- 运行态 → 就绪态
- 运行态 → 阻塞态
- 阻塞态 → 就绪态
进程控制
用 原语
实现进程控制
进程控制概念
进程控制:对系统中的所有进程实施有效的管理,具有 创建新进程、撤销已有进程、实现进程状态转换 等功能
就是实现进程的状态转换
用
原语
实现进程控制:
原语
:特点是执行期间不允许中断
,只能一气呵成,即 原子操作- 原语采用
关中断指令
和开中断指令
实现- 原语是一种特殊的程序
- 原语处于操作系统最底层,是最接近硬件的部分
- 原语程序运行时间短、调用频繁
进程控制相关原语
进程控制导致进程状态转换,无论哪个原语,要做的无非三类事情:
- 更新 PCB 中的信息:如 修改进程状态标志、将运行状态保存到 PCB、从 PCB 恢复运行环境
- 所有的进程控制原语一定都会修改进程状态标志
- 剥夺当前运行进程的 CPU 使用权必然需要保存其运行环境
- 某进程开始运行前必然要恢复其运行环境
- 将 PCB 插入合适的队列
- 分配、回收资源
创建原语——进程的创建
无 → 创建态 → 就绪态
- 申请空白 PCB
- 为新进程分配所需资源
- 初始化 PCB
- 将 PCB 插入就绪队列
撤销原语——进程的终止
就绪态 / 阻塞态 / 运行态 → 终止态 → 无
- 从 PCB 集合中找到终止进程的 PCB
- 若进程正在运行,立刻剥夺 CPU,将 CPU 分配给其他进程
- 终止其所有子进程
- 将该进程拥有的所有资源归还刚给父进程或操作系统
- 删除 PCB
阻塞原语——进程的阻塞
运行态 → 阻塞态
- 找到要阻塞的进程对应的 PCB
- 保护进程的运行现场,将 PCB 状态信息设置为 阻塞态,暂时停止进程运行
- 将 PCB 插入相应事件的等待队列
唤醒原语——进程的唤醒
阻塞态 → 就绪态
- 在时间等待队列中找到 PCB
- 将 PCB 从等待队列移除,设置进程为就绪态
- 将 PCB 插入就绪队列,等待调度
切换原语——进程的切换
运行态 → 阻塞态 / 就绪态 → 就绪态 → 运行态
- 将运行环境信息存入 PCB
- PCB 移到相应队列
- 选择另一个进程执行,并更新其 PCB
- 根据 PCB 恢复新进程所需的环境
进程通信
- 共享存储:
- 基于数据结构的共享
- 基于存储区的共享
- 消息传递:
- 直接通信方式
- 间接通信方式
- 管道通信
进程通信——各进程之间的信息交换
- 进程是分配操作系统资源的单位(包括内存地址空间),因此
各进程拥有独立的内存地址空间
- 为了保证系统安全性,一个进程不能直接访问另一个进程的地址空间,但有时进程之间的信息交换是必须的,因此操作系统必须提供一些进程间安全通信的办法
共享存储
在内存中设立一块两个进程共享的空间
- 两个进程对共享空间的
访问
必须是互斥
的- 互斥访问可以通过操作系统提供的工具实现
- 操作系统只负责提供共享空和同步互斥工具(如 P、V 操作)
基于数据结构的共享
- 基于固定的数据结构,比如共享空间里只能存放一个长度为 10 的数组
- 这种共享方式速度慢,限制多,是一种
低级通信
方式基于存储区的共享
- 在内存中画出一块共享存储区,数据的形式、存放位置都由进程控制,而不是操作系统
- 这种共享方式速度快,是一种
高级通信
方式
管道通信
管道是指用于连接读写进程的一个共享文件,有名 PIPE 文件
- 其实就是在内存中开辟一个大小固定的缓冲区
- 管道只能采用
半双工通信
,某一时间段内只能实现单向的传输;如果要实现双向同时通信,则需要设置两个管道- 各进程必须
互斥
的访问管道- 数据以
字符流
的方式写入管道,当管道写满
时,写进程
的write()
系统调用被阻塞
,等待读进程将数据取走;当读进程将数据全部取走后,管道变空
,此时读进程
的read()
系统调用将被阻塞
- 如果没写满,就不允许读;如果没读空,就不允许写
- 数据一旦被读出,就从管道中被抛弃,这意味着 读进程最多只能有一个,否侧可能会有读错数据的情况
消息传递
进程间的数据交换以
格式化的消息
Message 为单位
- 进程通过操作系统提供的
发送消息
、接收消息
两个原语
进行数据交换- 消息包含
消息头
和消息体
- 消息头:发送进程ID、接收进程ID、消息类型、消息长度等格式化的信息
直接通信方式
- 消息直接挂到接收进程的消息缓冲队列上
间接通信方式
- 消息要先发送到中间实体(邮箱)中,因此也称
信箱通信方式
线程
有的进程可能需要 ”同时“ 做很多事,而传统的进程只能串行地执行一系列程序,为此引入了
线程
,以增加并发度
- 传统的进程是程序执行流的最小单位
- 引入线程后,线程成为了程序执行流的最小单位
- 可将线程理解为轻量级进程
- 线程是一个基本的 CPU 执行单元,也是程序执行流的最小单位
- 引入线程后,不仅是 进程之间可以并发,进程内的各线程之间也可以
并发
,从而进一步提升了系统的并发度,使得一个进程内可以并发处理多个任务(如 QQ 内视频、文字聊天、传输文件)- 引入县城后,
进程
只作为 除 CPU 之外的系统资源的分配单元(如打印机、内存地址空间等都是分配给进程的)
引入线程带来的变化
- 资源分配、调度
- 传统进程机制中,进程是资源分配、调度的基本单位
- 引入线程后,进程是资源分配的基本单位,线程是调度的基本单位
- 并发性
- 传统进程机制中,只能进程间并发
- 引入线程后,各线程间也能并发,提升了系统并发度
- 系统开销
- 传统的进程间并发,需要切换进程的运行环境,系统开销很大
- 线程间并发,如果是同一进程内的线程切换,则不需要切换进程环境,系统开销小
- 引入线程后,并发带来的系统开销减小
线程的属性
- 线程是处理机调度的单位
- 多 CPU 计算机中,各线程可占用不同的 CPU
- 每个线程都有一个线程ID、线程控制块 TCB
- 线程也有就绪、阻塞、运行三种基本状态
- 线程几乎不拥有系统资源
- 同一进程的不同线程间共享进程的资源
- 由于共享内存地址空间,同一进程中的线程间通信甚至无需系统干预
- 同一进程中的线程切换,不会引起进程切换
- 不同进程中的线程切换,会引起进程切换
- 切换同进程中的线程,系统开销很小
- 切换进程,系统开销较大
线程的实现方式
用户级线程
User-Level Thread,ULT
- 用户级线程由应用程序通过线程库实现
- 所有的
线程管理工作
都由 应用程序负责 (包括线程切换)- 用户级线程中,
线程切换
可以在用户态
下完成,无需操作系统干预- 在用户看来,是有多个线程;但在操作系统内核看来,并意识不到线程的存在(用户级线程对用户不透明,对操作系统透明)
- 用户级线程,就是从用户视角出发,能看到的线程
内核级线程
Kernel-Level Thread,KLT;又称
内和支持的线程
- 内核级线程的管理工作由
操作系统内核
完成- 线程调度、切换等工作都由内核负责,因此内核级线程的切换,必然需要在
核心态
下才能完成- 内核级线程,就是从操作系统内核视角看,才能看到的线程
重点
操作系统只 ”看得见“ 内核级线程,因此只有内核级线程才是处理机分配的单位
多线程模型
在同时支持用户级线程和内核级线程的系统中,由几个用户级线程映射到几个内核级线程的问题,引入了
多线程模型
问题
- 多对一模型:多个用户级线程映射到一个内核级线程,每个用户进程只能对应一个内核级线程
- 优点:用户级线程的切换在用户空间即可完成,不需要切换到核心态,线程管理的系统开销小,效率高
- 缺点:当一个用户级线程被阻塞后,整个进程都会被阻塞,并发度不高。多个线程不可在多核处理机上并行运行
- 一对一模型:图如 "内核级线程" 的图。一个用户级线程映射一个内核级线程。每个用户进程有与用户级线程相同数目的内核级线程
- 优点:当一个线程被阻塞后,别的线程还可以继续执行,并发能力强。多线程可在多核处理机上并行执行
- 缺点:一个用户进程会占用多个内核级线程,线程切换由操作系统内核完成,需要切换到核心态,因此线程管理的成本高,开销大
- 多对多模型:n 个用户级线程映射到 m 个内核级线程上,n ≥ m。
- 集先前二种模型之所长