第二章 进程的描述与控制
2.1 前趋图和程序执行
2.1.1 前趋图
前趋图:一个有向无循环图,可记为DAG,用于描述进程之间执行的先后顺序。结点间的有向边则表示两个结点之间存在的偏序或前趋关系。
若Pi和Pj存在着前趋关系,克表示为(Pi,Pj)∈→,也可写成Pi→Pj,表示在Pj开始执行之前,Pi必须完成。
没有前趋的结点称为初始结点,没有后继的结点称为终止结点,每个结点具有一个重量,表示该结点所含有的程序量或程序执行时间。
下图a中存在前趋关系:P1→P2,P1→P3,P1→P4,P2→P5,P3→P5,P4→P6,P4→P7,P5→P8,P6→P8,P7→P9,P8→P9
image-20201122083555954
前趋图是不允许存在循环的,图b是不可能实现的前趋图。
2.1.2 程序顺序执行
执行时需要按照某种先后次序顺序执行,仅当前一程序段执行完后,才运行后一程序段。
程序顺序执行时的特征:
顺序性
处理机严格按照程序锁规定的顺序执行,每一操作必须在下一操作开始之前结束
封闭性
程序在封闭的环境下运行,程序运行时独占全机资源
可再现性
只要程序执行时的环境和初始条件相同,当程序重复执行时,无论停顿与否都可以获得相同的结果
2.1.3 程序并发执行
image-20201122092138011
只有在不存在前趋关系的程序之间才有可能并发执行。
程序并发执行时的特征:
间断性
程序在并发执行时,由于它们共享系统资源,以及为完成同一项任务而相互合作,致使在这些并发执行的程序之间形成了相互制约的关系。
失去封闭性
当系统中存在着多个可以并发执行的程序时,系统中各种资源被共享,致使其中任一程序在运行时,环境都必然会受到其它程序的影响。
不可再现性
由于失去了封闭性,其计算结果必将与并发程序的执行速度有关,使程序的执行失去了可再现性。
2.2 进程的描述
2.2.1 进程的定义和特征
进程:进程是程序的一次执行;进程是进程实体的运行过程,它是系统进行资源分配和调度的一个独立单位。
进程实体:程序段、相关的数据段和PCB
进程控制块PCB:描述进程的基本情况和活动过程,进而控制和管理进程。
进程的特征:
动态性
进程的实质是进程实体的执行过程。
由创建而产生,由调度而执行,由撤销而消亡。
进程是动态的,程序是静态的。
并发性
多个进程实体同存于内存中,且能在一段时间内同时运行。
独立性
进程实体是一个能独立运行、独立获得资源和独立接受调度的基本单位。
异步性
按各自独立的、不可预知的速度向前推进。
2.2.2 进程的基本状态及转换
进程的三种基本状态
就绪(Ready)状态
进程已处于准备好运行的状态,即进程已分配到除CPU以外的所有必要资源后,只要再获得CPU,便可立即执行。
执行(Running)状态
进程已获得CPU,其程序正在执行的状态。
阻塞(Block)状态
正在执行的进程由于发生某事件(如I/O请求、申请缓冲区失败等)暂时无法继续执行时的状态,亦即进程的执行受到阻塞。
三种基本状态的转换
image-20201122094645125
创建状态和终止状态
进程是由创建而产生。
向进程申请一个空白PCB,并向PCB中填写用于控制和管理进程的信息
为该进程分配运行时所必须的资源
把该进程转入就绪状态并插入就绪队列之中
终止
等待操作系统进行善后处理
将其PCB清零,并将PCB空间返还系统
image-20201122101843097
2.2.3 挂起操作和进程状态的转换
挂起操作,基于系统和用户以下需要:
终端用户的需要
父进程请求
负荷调节的需要
操作系统的需要
image-20201122102129743
2.2.4 进程管理中的数据结构
进程控制块PCB的作用:
作为独立运行基本单位的标志
能实现间断性运行方式
提供进程管理所需要的信息
提供进程调度所需要的信息
实现与其它进程的同步与通信
进程控制块PCB中的信息:
进程标识符
唯一地标识一个进程。
外部标识符
内部标识符
处理机状态
通用寄存器
指令计数器
程序状态字
用户栈指针
进程调度信息
进程状态
进程优先级
进程调度所需的其它信息
事件(阻塞原因)
进程控制信息
程序和数据的地址
进程同步和通信机制
资源清单
链接指针
进程控制块的组织方式
线性方式
将所有的PCB都组织在一张线性表中,将该表的首址存放在内存的一个专用区域中
链接方式
把具有相同状态进程的PCB分别通过PCB中的链接字链接成一个队列
索引方式
系统根据所有进程状态的不同,建立几张索引表
2.3 进程控制
操作系统内核
支撑功能
中断处理
时钟管理(时间片)
原语操作(由若干条指令组成,在执行过程中不允许被中断)
资源管理功能
进程管理
存储器管理
设备管理
进程图
用于描述进程间关系的一棵有向树。图中的结点代表进程。
image-20201122104213788
引起创建进程的事件
用户登录
作业调度
提供服务
应用请求
进程的创建
申请空白PCB
为新进程分配其运行所需的资源
初始化进程控制块PCB
将新进程插入就绪列
进程的终止
正常结束
异常结束
外界干预
进程终止过程
根据被终止进程的标识符,从PCB集合中检索出该进程的PCB,从中读出该进程的状态
若被终止进程正处于执行状态,应立即终止该进程的执行,并置调度标志为真,用于指示该进程被终止后应重新进行调度
若该进程还有子孙进程,还应将子孙进程也终止
将被终止进程所有全部资源或者归还给其父进程,或归还给系统
将被终止进程从所在队列中移出
引起进程的阻塞与唤醒的事件
向系统请求共享资源失败
等待某种操作的完成
新数据尚未到达
等待新任务的到达
进程阻塞过程
阻塞原语:block
阻塞是进程自身的一种主动行为。
进程唤醒过程
调用唤醒原语wakeup,将等待该事件的进程唤醒。
wakeup的过程是:
把被阻塞的进程从等待该事件的阻塞队列中移出,将其PCB中的现行状态由阻塞改为就绪,然后再将该PCB插入到就绪队列中
进程的挂起
挂起原语:suspend
进程的激活
挂起原语:active
2.4 进程同步
进程同步机制的主要任务:对多个相关进程在执行次序中进行协调,使并发执行的诸进程之间能按照一定的规则(或时序)共享系统资源,并能很好地相互合作,从而使程序的执行具有可再现性。
两种形式的制约关系
间接实现互斥,直接实现同步
间接相互制约关系
多个程序在并发执行时,由于共享系统资源致使这些执行程序之间形成相互制约的关系。
直接相互制约关系
前趋图
临界资源
诸进程间应采取互斥方式,实现对临界资源的共享。
临界区
程序代码中访问临界资源的部分。
while(TRUE)
{
进入区
临界区
退出区
剩余区
}
1
2
3
4
5
6
7
同步机制
空闲让进
忙则等待
有限等待:在有限时间内能进入自己的临界区,以免陷入“死等”状态
让权等待:进程不能进入临界区时应立即释放处理机
硬件同步机制
关中断
在进入锁测试之前关闭中断,直到完成锁测试并上锁之后才能打开中断。
Test-and-Set指令实现互斥
boolean TS(boolean *lock)
{
boolean old;
old = *lock;
*lock = TRUE;
return old;
}
do{
…
while TS(&lock)
critical section;
lock = FALSE;
remainder section;
}while(TRUE)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
利用Swap指令实现进程互斥
void swap(boolean *a, boolean *b)
{
boolean temp;
temp = *a;
*a = *b;
*b = temp;
}
do{
key = TRUE;
do{
swap(&lock,&key);
}while(key!=FALSE)
临界区操作;
lock = FALSE;
…
}while(TRUE)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
信号量机制
整型信号量
wait(S)和signal(S)被分别称为P、V操作。
wait(S){
while(S<=0)
S–;
}
signal(S){
S++;
}
1
2
3
4
5
6
7
8
记录型信号量
代表资源数目的整型变量value,一个进程链表指针list,用于链接上述所有等待进程。
typedef struct{
int value;
struct process_control_block *list;
}
wait(semaphore *S)
{
S->value–;
if(S->value<0) block(S->list);
}
signal(semaphore *S)
{
S->value++;
if(S->value<=0) wakeup(S->list);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
S->value的初值表示系统某类资源的数目,它的每次wait操作,意味着进程请求一个单位的该类资源,使系统中可供分配的该类资源数减少一个;当S->value<0时,表示该类资源已分配完毕,因此进程应调用block原语进行自我阻塞,放弃处理机,并插入到信号量链表S->list中。此时S->value的绝对值表示在该信号量链表中已阻塞的数目。
若S->value++后S->value≤0,则表示该信号量链表中仍有等待该资源的进程被阻塞,故调用wakeup原语,唤醒链表中的第一个等待进程。
AND型信号量
将进程在整个运行过程中需要的所有资源,一次性全部分配给进程,待进程使用完后再一起释放,只要尚有一个资源未能分配给进程,其它所有可能为之分配的资源也不分配给它。
信号量集
进程对信号量Si是该资源的分配下限值ti,要求Si≥ti,否则不予分配。一旦允许分配,进程对该资源的需求值为di,即表示资源占用量,进行Si=Si-di操作。
特殊情况
Swait(S,d,d):只有一个信号量S,允许每次申请d个资源,当少于d时,不予分配
Swait(S,1,1):一般的记录型信号量(S>1)或互斥信号量(S=1)
Swait(S,1,0):S≥1,允许多个进程进入某特定区;S=0,将阻止任何进程进入特定区
利用信号量实现进程互斥
两个信号量互斥
设mutex为互斥信号量,其初值为1,取值范围为(-1,0,1)。当mutex=1时,表示两个进程皆未进入需要互斥的临界区;当mutex=0时,表示有一个进程进入临界区运行,另外一个必须等待,挂入阻塞队列;当mutex=-1时,表示有一个进程正在临界区运行,另外一个进程因等待而阻塞在信号量队列中,需要被当前已在临界区运行的进程退出时唤醒。
代码描述
semaphore mutex=1;
PA(){
while(1){
wait(mutex);
临界区
signal(mutex);
剩余区
}
}
1
2
3
4
5
6
7
8
9
利用信号量实现前趋关系
Var a,b,c,d,e,f,g:semaphore: =0,0,0,0,0,0,0;
p1(){S1;signal(a);signal(b);}
p2(){wait(a);S2;signal©;signal(d);}
p3(){wait(b);S3;signal(e);}
p4(){wait©;S4;signal(f);}
p5(){wait(d);S5;signal(g);}
p6(){wait(e);wait(f);wait(g);S6;}
1
2
3
4
5
6
7
image-20201122121332514
管程机制
代表共享资源的数据结构以及由对该共享数据结构实施操作的一组过程所组成的资源管理程序共同构成了一个操作系统的资源管理模块,称之为管程。
管程的名称
局部于管程的共享数据结构说明
对该数据结构进行操作的一组过程
对局部于管程的共享数据设置初始值的语句
image-20201122122125995
管程和进程的不同
进程定义的是私有数据结构PCB,管程定义的是公共数据结构
进程是由顺序程序执行有关操作,管程进行同步操作和初始化操作
进程的设置目的在于实现系统的并发性,管程的设置目的则是解决共享资源互斥使用问题
进程为主动工作方式,管程为被动工作方式
进程具有动态性,管程是操作系统中的一个资源管理模块,供进程调用
2.5 经典进程的同步问题
设信号量→赋初值→编程(每一进程)
生产者-消费者问题
哲学家进餐问题
读者-写者问题
2.6 进程通信
低级进程通信(信号量)
效率低
通信对用户不透明
高级进程通信
使用方便
高效地传送大量数据
进程通信的类型
共享存储器系统
相互通信的进程共享某些数据结构或共享存储区,进程之间能够通过这些空间进行通信。
基于共享数据结构的通信方式
基于共享存储区的通信方式
管道通信系统
所谓“管道”,指用于连接一个读进程和一个写进程以实现它们之间通信的一个共享文件
消息传递系统
以格式化消息为单位,将通信的数据封装在消息中,并利用操作系统提供的一组通信命令,在进程间进行消息传递,完成进程间的数据转换
直接通信方式
发送进程利用OS所提供的发送原语,直接把消息发送给目标进程
间接通信方式
发送和接收进程,都通过共享中间实体的方式进行消息的发送和接收,完成进程间的通信。
客户机-服务器系统
套接字
基于文件型
基于网络型
远程过程调用
远程方法调用
消息传递通信的实现方式
直接消息传递系统
发送进程利用OS所提供的发送命令(原语),直接把消息发送给目标进程。
直接通信原语
对称寻址方式
send(receiver,message);
receive(sender,message);
非对称寻址方式
send(P,message);
receive(id,message);
消息的格式
进程的同步方式
通信链路
信箱通信
信箱的结构
信箱头:用于存放有关信箱的描述信息
信箱体:由若干个可以存放消息(或消息头)的信箱格组成,信箱格的数目已经每格的大小是在创建信箱时确定的
信箱通信原语
邮箱的创建和撤销
消息的发送和接收
信箱的类型
私用邮箱
公用邮箱
共享邮箱
直接消息传递系统实例
2.7 线程的基本概念
引入线程是为了减少程序在并发执行时所付出的时空开销,使OS具有更好的并发性
线程与进程的比较
调度的基本单位
进程是能独立运行的基本单位,在每次被调度时,都需要进行上下文切换,开销较大;
线程切换仅需保存和设置少量寄存器内容,切换代价远低于进程
并发性
都可以并发执行
拥有资源
进程可以拥有资源,并作为系统中拥有资源的一个基本单位;
线程并不拥有系统资源,而是仅有一点必不可少的、能保证独立运行的资源
独立性
进程间地址空间和资源互相独立;
线程间共享地址空间和资源
系统开销
进程需要切换上下文;线程没什么资源,开销小
支持多处理机系统
进程必须在单处理机上运行;
单进程中的多线程可分配到不同处理机上执行