2.1 前趋图和程序执行
2.1.1 前趋图
前趋图是一个有向无循环图,记为DAG,可用于描述程序/进程之间执行的前后关系,无循环关系可实现顺序执行。
2.1.2 程序的顺序执行
在计算机系统中只有一个程序在运行,这个程序独占系统中所有资源,其执行不受外界影响。一道程序执行完后另一道才能开始。
程序顺序执行的特点:
顺序性:一个程序开始执行必须要等到前 一个程序已执行完成。
封闭性:程序一旦开始执行,其计算结果不受外界因素影响。
可再现性:程序的结果与它的执行速度无关(即与时间无关),只要给定相同的输入,一定会得到相同的结果。
2.1.3 程序的并发执行
若干程序同时在系统中执行,这些程序的执行在时间上是重叠的,一个程序的执行尚未结束,另一个程序的执行已经开始。若干程序同时在系统中执行,这些程序的执行在时间上是重叠的,一个程序的执行尚未结束,另一个程序的执行已经开始。
程序并发执行的特点:
间断性
失去程序的封闭性:程序在并发执行时,是多个程序共享系统中的资源,因此这些资源的状态将由多个程序来改变。
不可再现性(如下例)
程序并发执行引发的问题:
协调各程序的执行顺序:例如,当输入的数据还未全部输入内存时,计算必须等待。
多个执行程序共享系统资源,程序之间可能会相互影响,甚至影响输出结果。
选择哪些、多少个程序进入内存执行?
内存中的执行程序谁先执行,谁后执行?
内存如何有效分配?
2.2 进程描述(进程基本概念)
2.2.1 进程的定义
进程的概念是60年代初首先由麻省理工学院的MULTICS系统和IBM公司的CTSS/360系统引入的。进程有很多各式各样的定义,如:
行为的一个规则叫做程序,程序在处理机上执行时所发生的活动称为进程。
一个具有一定功能的程序关于某个数据集合的一次运行活动。
进程是一个程序与其数据一道通过处理机的执行所发生的活动。
进程是指进程实体的运行过程,是系统进行资源分配和调度的一个独立单位。
进程实体(进程映像、进程):程序段、相关的数据段、进程控制块PCB。
为了描述和控制进程运行,OS为每个进程定义了一个数据结构——进程控制块(PCB)。PCB中记录了OS所需的、用于描述进程当前情况以及控制进程运行的全部信息。PCB是操作系统中最重要的记录型数据结构。
2.2.2 进程的特征
结构特征:由程序段、数据段、进程控制块三部分组成;
动态性:进程的实质是程序的执行过程;动态性是进程最基本的特征。进程实体具有一定的生命周期。
并发性:多个进程可同存于内存中,能在一段时间内同时运行;引入进程的目的正是为了使进程实体能够并发执行;程序不能参与并发执行。
独立性:进程是独立运行的基本单位,独立获得资源和调度的基本单位;
异步性:各进程按各自独立的不可预知的速度向前推进。
2.2.3 进程同程序的比较
程序是指令的有序集合,其本身没有任何运行的含义,是一个静态的概念。而进程是程序在处理机上的一次执行过程,它是一个动态的概念;
程序可以作为一种软件资料长期存在,而进程是有一定生命期的。程序是永久的,进程是暂时的;
进程更能真实地描述并发,而程序不能;
进程是由程序和数据、进程控制块三部分组成的;
进程具有创建其他进程的功能,而程序没有;
同一程序同时运行于若干个数据集合上,它将属于若干个不同的进程。同一程序可以对应多个进程。
2.2.4 进程的状态及转换
进程的三种基本状态:
不同系统设置的进程状态数目不同。进程有三种基本状态:Ready、Running、Block。进程在生命消亡前处于且仅处于三种基本状态之一。
就绪状态(Ready):当进程已经获得了除CPU以外的所有资源,一旦得到CPU,就立即可以运行,则这些进程所处的状态为就绪状态。
就绪队列:所有处于就绪状态的进程所在的队列。
运行状态(Running):正在运行的进程所处的状态为运行状态。
单处理机系统 一个进程处于运行状态
多处理机系统有多个进程处于运行状态
阻塞/等待状态(Blocked/Wait):若一进程正在等待某一事件发生(如等待输入/输出工作完成),这时即使给它CPU,它也无法运行,称该进程处于等待状态,或阻塞、睡眠、封锁状态。
阻塞队列:系统根据阻塞原因设置多个队列来管理处于阻塞状态的进程。
新建态和终止态:
新建态:进程由创建而产生。
为一个新进程创建必要的管理信息,保证进程的调度必须在创建工作完成以后进行,处于创建状态的进程,当获得了所需要的资源以及对PCB初始化工作完成后,便可以由创建状态进入就绪状态。
终止态:进程由终止而结束。
等待操作系统进行善后,然后,退出主存。
进入终止态的进程不再执行,但依然临时保留在系统中等待善后。一旦其他进程完成了对终止态进程的信息抽取之后,系统将删除该进程,将其PCB清零,把PCB空间返回给系统。
2.2.5 挂起操作和进程状态
挂起操作为进程增加新状态:挂起操作使某个进程处于静止状态。如果进程正在执行,挂起操作使他暂停执行;如果处于就绪状态,挂起操作使他暂不接受调度。与挂起操作对的就是激活操作。
引入挂起状态的原因:
终端用户的请求
父进程请求
负荷调节的需要
操作系统的需要
对换的需要
具有挂起状态的状态转换:
活动就绪(就绪状态)→静止就绪:对就绪的进程进行挂起操作,则该进程不能再被调度进入静止就绪状态
静止就绪→活动就绪(就绪状态):用相应的激活原语激活以后,重新进入活动就绪状态,进入就绪队列等待调度
活动阻塞(阻塞状态)→静止阻塞:用挂起原语对阻塞进程实施挂起操作则进入静止阻塞状态,只有在该进程所期待的事件发生以后就会转入静止就绪。
静止阻塞→活动阻塞(阻塞状态):利用激活原语激活以后进入活动阻塞状态。
2.2.6 进程管理中的数据结构——进程控制块(Process Control Block)
在计算机系统中,对每个资源和每个进程都设置了一个数据结构,用来表征其实体,其中包含了他们的标识、描述、状态等信息以及一批指针。
OS管理的这些数据结构一般分为四类:内存表、设备表、文件表和进程表(PCB)。
为了描述和控制进程运行,系统为每个进程定义了一个数据结构,称为进程控制块(PCB)。PCB中记录了OS所需的、用于描述进程当前情况以及控制进程运行的全部信息。PCB是操作系统中最重要的记录型数据结构。
PCB的作用是将一个不能独立运行的程序变成一个可以独立运行的基本单位,一个能与其他进程并发执行的进程。
OS利用PCB来对并发执行的进程进行控制和管理
PCB是OS感知进程存在的唯一标志。
进程与PCB是一一对应的。
PCB应常驻内存。
PCB的作用:
1.作为独立运行的基本单位的标志
2.能实现间断性运行方式
3.提供进程管理所需要的信息
4.提供进程调度所需要的信息
5.实现与其他进程的同步与通信
PCB的内容:
1.进程标识符:进程描述信息
进程标识符(process ID),唯一,通常是一个整数
外部标识符:进程名,通常基于可执行文件名
内部标识符:用户标识符(user ID);进程组关系
2.处理机状态(处理机上下文):CPU现场保护信息
寄存器值(通用、程序计数器、程序状态字PSW,栈指针)
指向赋予该进程的段/页表的指针
3.所拥有的资源和使用情况:
虚拟地址空间的现状
打开文件列表
4.进程调度与控制信息:
当前状态
优先级(priority)
代码执行入口地址
程序的外存地址
运行统计信息(执行时间、页面调度)
进程间同步和通信
阻塞原因
进程的队列指针
进程的消息队列指针
PCB组织方式:
1.线性方式 PCB表:
系统把所有进程的PCB组织在一起,并把它们放在内存的固定区域,就构成了PCB表。
PCB表的大小决定了系统中最多可同时存在的进程个数,称为系统的并发度。
2.链接方式
相同状态的进程PCB组成一个队列,不同状态对应多个不同的队列(就绪队列、阻塞队列等)。
3.索引结构
对具有相同状态的进程,分别设置各自的PCB索引表,存放这些进程PCB在PCB表中的地址。
2.3 进程控制
进程控制指对系统中的所有进程实施管理。
如:创建一个新进程;终止一个已完成的进程;终止一个因某事件而使其无法运行下去的进程;进程运行中状态的转换......进程控制一般由OS的内核中的原语来实现。
常用的进程控制原语:
创建原语Create
终止原语Destroy
阻塞原语Block、唤醒原语Wakeup
挂起原语Suspend、激活原语Active
2.3.1 进程创建
什么事件可以引起创建进程?
用户登录:系统为合法用户创建进程
作业调度:系统为被调度作业创建进程
提供服务:如用户程序需打印,系统创建打印进程
应用请求:由应用创建进程。如某应用可创建子进程完成输入、表格输出等
进程创建过程:
1.申请空白PCB
2.为新进程分配资源(物理资源和逻辑资源):如内存、设备、CPU等
3.初始化PCB(标识信息、处理机状态、处理机控制信息)
4.将新进程插入就绪队列
2.3.2 进程终止
引起进程终止的事件:
正常结束
异常结束:越界错误、保护错、特权指令错、非法指令错、I/O故障、运行超时、等待超时、算术运算错等
外界干预:操作员或OS干预;父进程请求;父进程终止,子孙进程被终止。
进程终止过程:
1.根据被终止进程的标识符,从PCB集合中检索出该进程的PCB;
2.若被终止进程处于执行状态,应立即终止执行,并置调度标志为真,调度其他进程;
3.结束该进程所有子孙进程的执行,以防止成为不可控进程;
4.将进程所拥有的资源交给父进程或系统进程;
5.释放PCB 。
2.3.3 进程的阻塞与唤醒
阻塞:当一个进程所期待的某一事件尚未出现时,该进程调用阻塞原语将自己阻塞。进程阻塞是进程自身的一种主动行为。
唤醒:处于阻塞状态的进程是绝不可能叫醒它自己的,必须由它的合作进程用唤醒原语唤醒它。(由于资源的释放唤醒)
进程在什么情况下会变为阻塞状态?
请求系统服务:如请求打印机
启动某种操作:如I/O操作
新数据还未到达:合作进程之间需要数据传递
无新工作可做:如发送进程发送完数据后
2.3.4 进程的挂起与激活
挂起:当出现了引起进程挂起的事件时,系统利用挂起原语将指定进程或处于阻塞状态的进程挂起。(暂时不参与资源竞争)
父进程请求挂起某个子进程;
系统利用挂起原语将指定进程或阻塞态进程挂起;
用户进程请求将自己挂起;
激活:当发生激活进程的事件时,系统利用激活原语将指定进程激活。
父进程请求激活某进程;
用户进程请求激活某进程;
2.4 进程通信
所谓进程通信是指进程之间信息交换。
P.V操作实现的是进程之间的低级通信,所以P.V为低级通信原语。它只能传递简单的信号,不能传递交换大量信息。
如果要在进程间传递大量信息可以用Send / Receive原语(高级通信原语)。
2.4.1 进程通信类型
1.共享存储器系统
(1)基于共享数据结构的通信方式
诸进程公用某些数据结构,进程通过它们交换信息。
低级通信
如生产者-消费者问题中的有界缓冲区。
(2)基于共享存储区的通信方式
高级通信,在存储器中划出一块共享存储区;
进程在通信前,向系统申请共享存储区中的一个分区,并指定该分区的关键字,若系统已经给其它进程分配了这个分区,则将该分区的描述符返回给申请者。
申请者把获得的共享存储分区连接到本进程上,此后可读写该公用的分区。
以上两种方式的同步互斥都要由进程自己负责。
2.管道通信
管道是最初的UNIX IPC形式,它能传送大量数据,被广泛采用。
所谓管道,是指用于连接一个读进程和一个写进程的文件,称pipe文件。
向管道提供输入的进程(称写进程),以字符流的形式将大量数据送入管道,而接受管道输出的进程(读进程)可从管道中接收数据。
管道可以是单工的,也可以是双工的。
管道:互斥、同步、确定对方存在
3.消息传递系统
进程间的数据交换以消息为单位,程序员利用系统的通信原语实现通信。
操作系统隐藏了通信的实现细节,简化了通信程序编制的复杂性,因而得到广泛应用。
消息传递系统可分为:
直接通信:发送进程直接把消息发送给接收者,并将它挂在接收进程的消息缓冲队列上。接收进程从消息缓冲队列中取得消息。
间接通信:发送进程将消息发送到某种中间实体中(信箱),接收进程从中取得消息。也称信箱通信。在网络中称为电子邮件系统。
直接通信与间接通信方式的主要区别?
前者需要两进程都存在,后者不需要。
4.客户机-服务器系统
套接字
远程过程调用和远程方法调用
2.4.2 消息传递通信的实现方法
直接通信方式:
1.直接通信原语
对称寻址(发送进程和接受进程显示提供标识符)
Send(Receiver,message);
Receive(Sender,message);
非对称寻址:
Send(P,message);//发送消息给进程P
Receive(id,message);//接收进程无需命名发送进程,只填写表示源进程的参数
2.消息的格式
网络操作系统的消息格式比较复杂;
消息分成消息头和消息正文组成;
定长消息格式(适用于办公自动化)和变长消息格式(适用于较长消息的发送)。
3.进程同步方式
发送进程阻塞、接收进程阻塞
发送进程不阻塞、接收进程阻塞
发送进程和接收进程均不阻塞
4、通信链路
(1)由发送进程在通信之前,用显式的“建立连接”命令请求系统为之建立一条通信链路,用完后也显式拆除,主要用于计算机网络中。
(2)发送进程只需利用系统提供的发送命令,系统会自动地为之建立一条链路,主要用于单机系统。
根据连接方法,可分点对点连接通信链路和多点连接链路。
根据通信方式不同,可分为单向通信链路和双向链路。
根据链路容量不同,可分为无容量通信链路和有容量通信链路。
间接通信方式——信箱通信
私用信箱:用户进程为自己创建的信箱,是进程的一部分。只有自己有权读,可采用单向链路实现。
公用信箱:由操作系统创建,所有系统核准进程都可使用,采用双向通信链路实现。
共享信箱:由某进程创建并指明可共享,则拥有者和共享者可使用。
信箱使用规则
若发送信件时信箱已满,则发送进程被置为“等信箱”状态,直到信箱有空时才被唤醒
若取信件时信箱中无信,则接收进程被置为“等信件”状态,直到有信件时才被唤醒
信箱通信原语——Send原语
send(MailBox,M):把信件M送到指定的信MailBox
步骤:
查找指定信箱MailBox ;
若信箱未满,则把信件M送入信箱且唤醒“等信件”者;
若信箱已满,置发送信件进程为“等信箱”状态;
信箱通信原语——Receive原语
receive(MailBox,X):从指定信箱MailBox中取出一封信,存放到指定的地址X中
步骤:
查找指定信箱MailBox ;
若信箱中有信,则取出一封信存于X中且唤醒“等信箱”者;
若信箱中无信件,置接收信件进程“等信件”状态;
2.5 线程
2.5.1 线程的引入
进程是一个资源分配的基本单位。
进程是一个可独立调度和分派的基本单位。
进程作为一个资源拥有者,在创建、撤消、切换中,系统必须为之付出较大时空开销。所以系统中进程的数量不宜过多,进程切换的频率不宜过高,但这也就限制了并发程度的进一步提高。
引入进程的目的是为了使多个程序更好的并发执行,改善资源利用率、提高系统效率。引入线程则是为了减少并发执行时所付出的时空开销,使并发粒度更细、并发性更好。
线程的产生:
将进程的上述两个属性分开:线程作为调度和运行的基本单位,但不同时作为独立分配资源的单位;线程会被频繁调度和切换。进程作为拥有资源的单位,不进行频繁切换。线程因而产生。在引入线程的OS中,线程是进程中的一个实体,是进程的一部分,是被系统独立调度和分派的基本单位。
关于调度:
系统调度的基本单位是线程而不是进程。每当创建一个进程时,至少要同时为该进程创建一个线程,否则该进程无法被调度执行。一个线程可以创建和撤消另一个线程;同一进程中的多个线程之间可以并发执行。
关于资源:
线程基本不拥有系统资源,只拥有少量必不可少的资源:程序计数器、一组寄存器等。
2.5.2 线程与进程的比较
线程具有进程的许多特征,在引入线程的OS中,每一进程都拥有至少一个线程。
线程具有进程的许多特征,故又称轻型进程,传统进程称重型进程。
1.独立调度和运行的基本单位:线程切换的代价远小于进程切换,同一进程中线程的切换不会引起进程的切换。
2.更好的并发性:不同进程的多个线程之间可以并发执行,一个进程内的多个线程也可以并发执行。
3.轻型实体:线程基本不拥有资源。仅拥有一点必不可少的资源,多个线程还可能共享进程所拥有的资源。
4.独立性:同一进程中不同线程的独立性会低一些
5.系统开销:线程创建撤销的开销上下文的切换远低于进程。
6.支持多处理机
2.5.3线程的状态
线程状态:运行、就绪和阻塞三种状态。线程的状态转换类似于进程。
线程的两种阻塞方式:
阻塞进程方式:对某些线程实现机制,当线程被阻塞时,所在进程也转换为阻塞态,即使这个进程存在另一个处于就绪态的线程。
阻塞线程方式:如果存在另外一个处于就绪态的线程,则调度该线程进入运行状态,否则进程才转换为阻塞态。
2.5.4 线程控制块TCB
TCB(Thread control block)标志线程存在的数据结构, 其中包含对线程管理需要的全部信息。
内容:线程标识、线程运行状态、寄存器、优先级、堆栈指针、线程存储区。
2.5.5 多线程操作系统中进程属性
进程是一个拥有资源的基本单位;
多个线程可以并发执行,一个进程至少要包含一个线程。进程为这些线程提供资源以及运行环境,使他们能够并发执行。每一个线程都属于某一个特定进程。
进程已经不是可执行的实体:把线程作为独立运行和调度的基本单位。
2.5.6 OS对线程的实现机制
从实现的角度看,线程可分为三种:
1.内核支持线程KLT (Kernal Supported/Level Thread)
线程是依赖于内核的,即无论是用户进程中的线程,还是系统进程中的线程,它们的创建、撤消、切换都由内核实现。
以线程为基础进行调度
所有线程管理由核心完成
内核维护进程和线程的上下文
线程之间的切换需要内核支持
时间片分配给线程,所以多线程的进程获得更多CPU时间
一个线程发起系统调用而阻塞,不会影响其他线程的运行
内核级线程的优点和缺点:
优点:
对多处理器,核心可同时调度同一进程的多个线程,并发程度更高;
阻塞是在线程一级完成。即进程中的一个线程被阻塞了,内核能调度同一进程的其它线程占有处理器运行。
切换开销更小
提高系统的执行速度和效率
缺点:
应用程序线程在用户态运行,线程管理与调度是在核心态,同一进程内的线程频繁切换时,调用内核,线程切换时要做模式切换,导致速度下降
2.用户级线程ULT(User Level Thread)
对于这种线程的创建、撤消和切换,都不用系统调用来实现。内核并不知道用户级线程的存在。
这种线程的创建、撤消和切换,都不用系统调用来实现。ULT与内核无关,线程的控制都在用户空间,与内核无关。应用进程利用线程库提供创建、同步、调度和管理线程的函数来控制用户线程。对于设置了用户级线程的系统,其调度仍以进程为单位进行;若设置的是内核支持线程,则调度以线程为单位进行。
用户级线程的优点和缺点:
优点:
线程切换是线程库在用户态进行,不调用核心,节省了模式切换的开销。
调度是应用程序特定的:可以选择最好的算法对自己的线程进行管理和调度。
ULT可运行在任何操作系统上(只需要线程库),可在一个不支持线程的OS上实现,与平台无关。
缺点:
线程执行系统调用时,不仅该线程被阻塞,且进程内的所有线程会被阻塞。
纯ULT中,多线程应用不能利用多处理机的优点。内核给一个进程仅分配一个CPU(不知道进程中有线程),进程中仅有一个线程能执行。即同一进程中的两个线程不能同时运行于两个处理器上。
3.混合式线程
是KLT与ULT的混合;
混合系统:内核支持KLT多线程的建立、调度和管理,也提供线程库,允许应用程序建立、调度和管理ULT。应用程序的多个ULT映射成一些KLT,程序员可按应用需要和机器配置调整KLT数目,以达到较好效果。
混合系统的优点:一个应用中的多个线程能同时在多处理器上并行运行,且阻塞一个线程时并不需要封锁(阻塞)整个进程。
三种不同模型:
多对一:多个用户线程映射到一个内核控制线程
一对一:每一个用户线程映射到一个内核线程
多对多:多个用户线程映射到多个内核线程
2.5.7 线程实现
1.内核支持线程:
2.用户级线程:运行时系统和内核控制线程(LWP)