第7章 进程和线程
7.1 进程的概念
进程定义:
进程是指一个具有一定独立功能的程序在一个数据集合上的一次动态执行的过程。
进程包含了正在运行的一个程序的所有状态信息
组成:
- 代码
- 数据
- 状态寄存器:CPU状态CR0、指令指针IP
- 通用寄存器:AX、BX、CX
- 进程占用系统资源:打开文件、已分配内存
进程的特点:
- 动态性:客动态地创建、结束进程
- 并发性:进程既可以被独立调度并占用处理机运行
- 独立性:不同的进程的工作不相互影响
- 制约性:因访问共享数据/资源或进程间同步而产生制约
进程与程序的联系:
- 进程是操作系统处于执行状态程序的抽象
程序 = 文件(静态的可执行文件)
进程 = 执行中的程序 = 程序 + 执行状态 - 同一个程序的多次执行过程对应为不同进程
如命令“ls”的多次执行对应多个进程 - 进程执行需要的资源
内存:保存代码和数据
CPU:执行指令
进程与程序的区别:
- 进程是动态的,程序是静态的
程序是有序代码的集合
进程是程序的执行,进程有内核态/用户态 - 进程是暂时的,程序是永久的
进程是一个状态变化的过程
程序客长久保存 - 进程与程序的组成不同
进程的组成包括程序、数据和进程控制块
7.2 进程控制块(PCB,Process Control Block)
概念:操作系统管理控制进程运行所用的信息集合
- 操作系统用PCB来描述进程的基本情况以及运行变化的过程
- PCB是进程存在的唯一标志,每个进程都在操作系统中有一个对应的PCB
使用:
-
进程创建时生成该进程的PCB
-
进程终止时回收它的PCB
-
通过对PCB的组织管理来实现对进程的组织管理
-
PCB具体包含什么信息?如何组织的?进程的状态转换?都与进程控制块有关
进程控制块的内容
- 进程标识信息
PID:进程号
UID等 - 处理机现场保存
SP 堆栈指针:记录堆栈现场
指令指针:记录进程运行到哪 - 进程控制信息
调度和状态信息:进程和处理机使用情况调度
进程间通信信息:进程间通信相关的各种标识
存储管理信息:指向进程映像存储空间数据结构
进程所用资源:进程使用的系统资源,如打开文件等
有关数据结构连接信息:通过与PCB相关的进程队列实现
进程控制块的组织:
- 链表
同一状态的进程的PCB组织成一链表,多个状态对应多个不同的链表。比如就绪链表、阻塞链表 - 索引表
同一状态的进程归入一个索引表(由索引表指向PCB),多个状态对应多个不同的索引表。
7.3 进程状态
进程生命周期划分:划分在不同操作系统中可能不同,但是大致可以分为:
- 进程创建
引起进程创建的情况:
系统初始化时
用户请求创建一个新进程
正在运行的进程执行了创建进程的系统调用 - 进程就绪
- 进程执行
内核选择一个就绪的进程,让它占用处理机并执行 - 进程等待:只有进程自身才知道何时需要等待某种事件的发生
进程进入等待(阻塞)的情况:
请求并等待系统服务,无法马上完成
启动某种操作,无法马上完成
需要的数据没有到达 - 进程抢占
高优先级进程就绪
进程执行当前时间用完 - 进程唤醒:进程只能被别的进程或操作系统唤醒
被阻塞进程需要的资源得到满足
被阻塞的进程等待的事件到达 - 进程结束
正常退出(自愿的)
错误退出(自愿的)
致命错误(强制性的)
被其他进程所杀(强制性的)
进程切换
7.4 三状态进程模型
- 创建与退出只是两个短暂的状态,除此之外简化为三个状态:就绪、运行、等待。装填变迁如下图
运行状态:进程正在处理机上运行
就绪状态:进程获得了除处理机之外的所需资源,得到处理机即可运行
等待状态:进程正在等待某一事件的出现而暂停运行
两种过渡的状态:
创建状态:一个进程正在被创建,还没被转到就绪状态之前的状态
结束状态:一个进程正在从系统中消失时的状态,这是因为进程结束或由于其他原因所导致
7.5 挂起进程模型
-
处于挂起状态的进程映像在磁盘上,目的是减少进程占用内存。也就是说挂起就是把一个处于就绪或者等待状态的进程从内存转存到外存,通常选择低优先级进程进行挂起。
-
等待挂起状态:进程在外存并等待某事件的出现
-
就绪挂起状态:进程在外存,但只要进入内存,即可运行
与挂起相关的状态转换
- 挂起:把一个进程从内存转到外存
- 等待到等待挂起:没有进程处于就绪状态或就绪进程要求更多的内存资源。
- 就绪到就绪挂起:当有高优先级等待(系统认为会很快就绪的)进程和低优先级就绪进程
- 运行到就绪挂起:对抢先式分时系统,当有高优先级等待挂起进程因事件出现而进入就绪挂起(这种情况较少)
在外存时的状态转换
- 等待挂起到就绪挂起:当有等待挂起进程因相关事件出现
解挂/激活(activate):外存->内存
就绪挂起->就绪:现在没有就绪进程;当前的就绪挂起进程的优先级高于就绪进程;
等待挂起->等待:当一个进程释放足够的内存时,系统会把一个高优先级的等待挂起进程(系统认为会很快出现所等待的事件发生) 转为等待进程。
状态队列:由操作系统来维护一组队列,表示系统中所有进程的当前状态
- 不同的状态分别用不同的队列来表示(就绪队列,各种类型的阻塞队列等);
- 每个进程的PCB都根据它的状态加入到相应的队列当中,当一个进程的状态发生变化时,它的PCB从一个状态队列中脱离,加入到另一个状态队列里。
从进程角度看待OS
- 用进程的观点来看待OS,OS包括 用户进程,磁盘管理进程,终端进程等;
以进程为基本结构的OS包括:
- 最底层scheduler为CPU的调度程序(包括中断处理等);
- 上面一层为一组各式各样的进程。
线程
7.6 线程的概念
引入原因:
-
一个进程内部可能有多种事件可以并发地执行,比如播放音乐时,可以拆分为磁盘读取、解码和播放三个子流程,读取主要是I/O操作,解码主要是CPU工作,这两者是可以并发执行的。
-
因此很多时候需要在进程内部增加一类实体,满足以下特性:
- 实体之间可以并发执行、
- 实体之间共享相同的地址空间。
-
这种实体就是线程(Thread)
定义:线程是进程的一部分,描述指令流执行状态,它是进程中的指令执行流的最小单元,是CPU调度的基本单位。
- 进程的资源分配角色:进程由一组相关资源构成,包括地址空间(代码段、数据段)、打开的文件等各种资源。
- 线程的处理机调度角色:线程描述在进程资源环境中的指令流的执行状态。每个线程有自己独立的指令指针等。
进程和线程的关系
线程= 进程-共享资源
线程的优点:
- 一个进程中可以同时存在多个线程
- 线程之间可以并发地进行
- 线程之间可以共享地址空间和文件等资源
线程的缺点:
- 一个线程的崩溃,会导致其所属进程的所有线程崩溃。
线程与进程的比较:
- 线程是进程的一部分,一个进程可以包含多个线程
- 线程是资源分配的单位,线程是CPU调度单位;
- 进程拥有完整的资源平台,而线程只独享指令流执行的必要资源,如寄存器,栈。
- 线程同样由就绪,阻塞(等待),执行三种基本状态,同样具有状态之间的转换关系。
- 线程能减少并发执行的时间和空间开销:
- 线程的创建时间比进程短
- 线程的终止时间比进程短
- 同一进程内的线程切换时间比进程短
- 由于同一进程内各线程共享内存和文件资源,可直接进行不通过内核的通信。
7.7 用户线程
线程三种实现方式:
1,用户线程:
- 由一组用户级的线程库函数来完成线程的管理,包括线程的创建,终止,同步和调度等。如POSIX Pthreads等。
- 优点:
- 不依赖于操作系统内核,内核不了解用户线程的存在。可以用于不支持线程的多进程操作系统
- 在用户空间实现的线程机制;每个进程有私有的线程控制块(TCB)列表,来跟踪记录它各个线程的状态信息(PC/栈指针/寄存器);TCB由线程库函数来维护;
- 同一进程内的用户线程切换速度快;无需在用户态与核心态之间切换
- 允许每个进程拥有自己的线程调度算法
- 缺点:
- 线程发起系统调用而阻塞时,整个进程进入等待
- 不支持基于线程的处理机抢占;除非当前运行线程主动放弃,它所在的线程的其他线程无法抢占CPU
- 只能按进程分配CPU时间;多个线程进程中,每个线程的时间片较少。
2,内核线程:在内核中实现
- 由内核通过系统调用实现的线程机制,由内核完成线程的创建、终止和管理。如Windows、Linux等
- 特点:
- 由内核维护PCB和TCB
- 线程执行系统调用而被阻塞不影响其他线程
- 线程的创建、终止和切换开销相对较大;因为通过系统调用/内核函数,在内核空间实现
- 以线程为单位进行CPU时间分配,多线程的进程可以获得更多CPU时间。
3,轻量级(轻权)进程:在内核中实现,支持用户线程
- 内核支持的用户线程,一个进程可以有一个或多个轻量级进程,每个轻权进程由一个单独的内核线程来支持。如Solaris。最后这个被证实优点没有被很好地体现出来。
用户线程与内核线程的对应关系:
- 可以有如下图多种方式,最后证明一对一是最优的: