第2章 进程管理

进程管理

1)进程与线程

2)处理器调度

3)进程同步

4)死锁

2.1 进程与线程

知识框架:
在这里插入图片描述

2.1.1 进程的概念和特性

1.进程的概念

——为何引入:多道程序下,允许多个程序并发执行,此时他们将失去封闭性,并具有间断性以及不可再现性的特征。引入进程,以便于更好的描述和控制多道程序的并发执行,实现现代OS的并发性和共享性(最基本的两个特性)
——系统用PCB来描述进程的基本情况和运行状态,进而控制和管理进程。由程序段、相关数据段和PCB三部分组成进程映像(即进程实体)
进程映像是静态的,进程则是动态的
——进程定义:进程是进程实体的运行过程,是系统进行资源分配和调度的独立单位。

2.进程的特性

1)动态性——最基本的特性

2)并发行

3)独立性

4)异步性

5)结构性

2.1.2 进程的状态与转换

1)运行状态

2)就绪状态

3)阻塞状态

4)创建状态:申请空白PCB->填入控制和管理进程信息->系统分配必要资源->转入就绪

5)结束状态

状态转化图如下:
在这里插入图片描述
注意区别就绪状态和等待状态:
就绪状态仅缺少处理机,只要获得处理机资源就立即执行;等待状态是指需要其他资源(除了处理机)或等待某一事件。在分时系统的时间片轮转机制中,进程在运行中实际上是频繁的转换到就绪状态的;而其他资源(如外设)的使用和分配或者某一事件的发生(如I/O操作完成)相对时间较长,这样来看,区分很有必要。

2.1.3 进程控制

1)进程的创建与终止
在这里插入图片描述
3)进程的阻塞与唤醒
在这里插入图片描述
4)进程切换
切换过程:
1:保存处理机上下文
2:更新PCB
3:进程PCB移入相应队列,如就绪、阻塞等队列
4:选择另一个进程执行,并更新其PCB。
5:更新内存管理的数据结构
5)恢复处理机上下文
——注意:进程切换与处理机模式切换是不同的,模式切换时,处理机逻辑上可能还在同一进程中运行。还有,”调度“与“切换”区别,调度是决策,切换是实际分配行为。一般,先有资源调度,后有进程切换。

2.1.4 进程的组织

1.进程控制块(PCB)

2.程序段

3.数据段

2.1.5 进程的通信

进程的通信是指进程间的信息交换。PV操作是低级通信方式,高级通信是指以较高的效率传输大量数据的通信方式。主要分三类:

1.共享存储

2.消息传递

3.管道通信(半双工通信,某一时刻单向传输)

2.1.6 线程概念与多线程模型

1.线程的基本概念

——为何引入:减少程序在并发执行时的时空开销,提高OS的并发性能
线程可理解为”轻量级进程“,是基本的CPU执行单元,是程序执行的最小单元,由线程ID、程序计数器、寄存器集合和堆栈组成。线程是进程中的一个实体,是被独立调度和分配的基本单元,线程不拥有系统资源,只拥有一点在运行时必不可少的资源
——引入线程之后,进程只作为处CPU以外系统资源的分配单位,线程则作为处理机的分配单元。一个线程内有多个进程,如果线程的切换在同一个进程内,则只需很少的时空开销

2.线程与进程的比较

在这里插入图片描述

3.线程的属性

首先,同一进程或不同进程的线程都可以并发执行
1)线程是一个轻型实体
2)不同线程可以执行相同的程序
3)同一进程中的各个线程共享该进程拥有的资源
4)线程是处理机的独立调度单位,多个线程可以并发执行
5)线程同进程一样也具有生命周期
线程提出有利于提高系统并发性的理解:有了线程,线程切换时,进程可能切换,也可能不切换,一平均每次切换所需时空开销就小了。

4.线程的实现方式

分为用户级线程内核级线程
在这里插入图片描述

5.多线程模型

1)多对一,即多个用户级线程映射到一个内核级线程,线程管理在用户空间完成
优点:效率高
缺点:当一个进程在使用内核服务时阻塞,整个进程都会阻塞;多个进程不能运行在处理机。
1)一对一,即一个用户级线程映射到一个内核级线程
不容易阻塞,但效率低
3)多对多,即n个用户级线程映射到m个内核级线程(m<=n)
特带:上述两模型折中,既克服了多对一并发度不高,又克服了一对一模型的一个用户进程占用太多内核级进程,开销太大的缺点。

2.2处理机调度

本节框架:
在这里插入图片描述
处理机调度引入:合理的处理计算机软硬件资源

2.2.1调度的概念

1.调度的基本概念

——在多道程序中,进程数量往往多于处理机个数,进程争夺处理机现象在所难免,因此要对处理机进行分配,就是从就绪队列中,按照一定算法(公平、高效)选择一个进程分配处理机给予运行,以实现程序的并发执行。

2.调度的层次

在这里插入图片描述

3.三级调度的联系

1)作业调度为进程活动做准备,进程调度使进程正常活动起来,中级调度则将暂时不能运行的进程挂起,中级调度又称内存调度,处于两者之间
2)调度频率从作业到内存到进程递减
3)进程调度是最基本的,不可缺少
说明:作业是用户提交的,进程则有系统自动生成。作业以用户任务为单位,进程以OS控制为单位

2.2.2调度的时机、切换与过程

——进程调度和切换程序是OS内核程序,当请求调度事件发生后,才可能会运行进程调度程序,当调度了新的就绪进程后,才有可能进行进程间的切换。
不能立刻进行处理机调度的情况:
在这里插入图片描述

2.2.3进程调度方式

1)非剥调度夺方式
2)剥夺调度方式

2.2.4调度准则

在这里插入图片描述

2.2.5调度的典型方法

在这里插入图片描述
说明:
1)高响应比优先调度算法、时间片轮转法、多级反馈队列调度,适用于分时系统;抢占式优先级调度算法适用于实时系统
2)时间轮转法是绝对可抢占的,此算法增加了系统开销,吞吐量和周转t不如批系统,但快速响应t使得用户和计算机交互,改善了人机环境,满足了用户需求。

2.3进程同步

知识框架:
在这里插入图片描述

2.3.1进程同步的基本概念

1.临界资源

定义:一次仅允许一个进程使用,如打印机,共享变量等
把访问临界资源的那段代码称为临界区
临界资源可划分四部分:
1)进入区,在此设置访问临界区的标志,防止其他进程同时进入
2)临界区,访问临界区的那段代码
3)退出区,将正在访问临界区的标志清除
4)剩余区

do{
	entry section;       //进入区 
	critical section;    //临界区 
	exit section;        //退出区 
	remainder section;   //剩余区 
}while(true);

2.同步

同步是指为完成某种任务而建立两个或者多个进程,这些进程因为需要在某些位置上的协调他们的工作次序而等待、传递信息而产生的制约关系。

3.互斥

互斥是指当一个进程进入临界区使用临界资源时,另一个进程必须等待,当占用临界资源的进程退出临界区后,才允许另一进程访问此临界资源。
为禁止两个进程同时进入临界区,同步机制应该遵守以下规则:
1)空闲让进
2)忙则等待
3)有限等待
4)让权等待

2.3.2实现临界区互斥方法

1.软件方法

1)单标志法
turn=0,则允许P0进入。
缺点:违背"空闲让进",两个进程必须交替进入临界区,若某个进程不再进入临界区,则另一个进程也无法进入临界区。

P0进程:                      P1进程:
while(turn);                 while(turn);
critical section;            critical section;  
trun=1;                      turn=0;
remainder section            remainder section;

2)双标志先检查
优点:不用交替进入,可连续使用
缺点:违背“忙则等待”,Pi和Pj可能同时进入临界区,按1,2,3,4执行时,会同时进入临界区。即在检查对方flag之后和切换自己flag之前有一段时间,结果都检查通过

Pi进程:                      Pj进程:
while(flag[j]);1         while(flag[i]);2   //进入区 
flag[i]=true;  3            flag[j]=true;4    //进入区 
critical section;            critical section;   //临界区 
flag[i]=false;               falg[j]=false;      //退出区 
remainder section;           remainder section;  //剩余区

3)双标志后检查
缺点:可导致”饥饿“现象,当两个进程几乎同时想进入临界区,分别把自己的flag置true,并且检测对方状态,发现对方也想进入临界区,结果谁也进不了,从而“饥饿”

Pi进程:                      Pj进程:
flag[i]=true;                flag[j]=true;       //进入区
while(flag[j]);              while(flag[i]);     //进入区
critical section;            critical section;   //临界区 
flag[i]=false;               falg[j]=false;      //退出区 
remainder section;           remainder section;  //剩余区 

4)Peterson‘s Algorithm。
优点:即可互斥访问,也不会“饥饿”

Pi进程:                      Pj进程:
flag[i]=true;turn=j;         flag[j]=true;turn=i;
while(flag[j]&&turn==j);     while(flag[i]&&turn==i)
critical section;            critical section;
falg[i]=false;               flag[j]=false;
remainder section;           remainder section; 

具体如下:考虑Pi进程,若设置flag[i]=true,表示Pi进程想进入临界区,同时turn=j,如果Pj已在临界区,则符合Pi内while条件,则Pi不能进入临界区。若Pj不在临界区,while不符合,则Pi顺利进入临界区。

2.硬件实现方法

1)中断屏蔽
CPU只有在中断时才引起进程切换
2)硬件指令方法
TestAndSet指令:
TST(Test And Set lock)伪代码

do{
	......
	while(TST(&lock));
	critical section;
	lock=false;
	......
}while(true);

分析:
1)当进程退出临界区时置lock为false,会唤醒处于就绪状态的进程。
2)等待进入临界区的进程会一直停留在while(TST(&lock)循环中,不会主动放弃CPU,违反“让权等待”

2.3.3信号量

1)整形信号量
被定义于表示资源个数的整型量S。当S<=0时,会循环测试,未遵循“忙则等待”
2)记录型信号量(遵循“让权等待”)
数据结构如下:

typedef struct{
	int value;
	struct process *L;
} semaphore; 

记录型信号量S中value意义:
1)初值表示系统中某类资源的个数
2)S.value<0,表示系统已经没有可用的此类资源
3)S.value<0,其绝对值表示S.L中因等待该资源而阻塞的进程个数

2.3.4管程

引入:为了解决临界区分散带来的管理和控制问题
组成:
1)局部于共享结构数据说明
2)对该组数据结构进行操作的一组过程
3)对局部于管程的共享数据设置初始值的语句
emm,很像一个抽象类,有木有

2.3.5经典同步问题锦集

1)生产者和消费者

semaphore mutex=1;    
semaphore empty=n;   //空缓冲区 
semaphore full=0;    //初始化缓冲区为空 
producer(){
	while(true){
		prodece an item in nextp;
		P(empty);  //用什么,P一下
		P(mutex); 
		add next to buffer;
		V(mutex); 
		V(full);  //提供什么,V一下 
	}
}
consumer(){
	while(true){
		P(full);
		P(mutex);
		remove an item from buffer;
		V(mutex);
		V(empty);
		consume the item;
	}
}

注意:对empty和full变量的P操作必须放在对mutex的P操作之前,否则有可能出现死锁。(死锁后面介绍)
2)读者——写者问题
3)哲学家进餐问题(5个哲学家为例)
思路:当一个哲学家两边都有筷子可用时,才允许他抓起筷子

semaphore chopstick[5]={1,1,1,1,1};
semaphore mutex=1;
Pi(){
	do(){
		P(mutex);
		P(chopstick[i]);
		P(chopstick[(i+1])%5);
		V(mutex);
		eat;
		V(chopstick[i]);
		V(chopstick[(i+1)%5]);
		think;
	}while(true);
}

4)吸烟者问题
问题描述:一个系统中有三个吸烟者进程和一个供应者进程。每个抽烟者不停卷烟并抽掉。抽烟者需要三种材料:烟草、纸和胶水。三个抽烟者中,1号有烟草,2号有纸,3号有胶水,供应者进程无限提供这三种材料,供应者每次将两种材料放桌上,拥有剩下那种材料的抽烟者卷烟并抽掉它,并给提供者一个信号告诉其完成了,供应者就放另外两种材料在桌上,一直重复这个过程。

int random;            //存储随机数 
semaphore offer1=0;    //烟草和纸组合 
semaphore offer2=0;    //烟草和胶水组合 
semaphore offer3=0;    //纸和胶水组合 
semaphore finish=0;    //定义信号量表示烟是否抽完 
process P1(){
	while(true){
		random=任取随机数;
		random=random%3; 
		if(random==0)
		   V(offer1);   //提供烟草和纸 
		else if(random==1)
		   V(offer2);   //提供烟草和胶水 
		else
		   V(offer3);   //提供纸和胶水 
		任意两种材料放桌上;
		P(finish); 
	}
}
process P2(){       //拥有烟草者 
	while(1){
		P(offer3);
		拿纸和胶水,卷烟,抽烟;
		V(finish); 
	}
}
process P2(){       //拥有纸者 
	while(1){
		P(offer2);
		拿烟草和胶水,卷烟,抽烟;
		V(finish); 
	}
}
process P2(){       //拥有胶水者 
	while(1){
		P(offer1);
		拿烟草和纸,卷烟,抽烟;
		V(finish); 
	}
}

2.4死锁

知识框架:
在这里插入图片描述

2.4.1死锁的概念:

1.死锁的定义

——所谓死锁是指多个进程因竞争资源而造成的一种僵局(互相等待),若无外力作用,这些进程将无法向前推进。

2.死锁产生的原因

1)系统资源的竞争
2)进程的推进顺序非法
3)死锁产生的必要条件
**互斥条件
**不可剥夺条件
**请求和保持条件
**循环等待条件:

2.4.2死锁的处理策略

1)死锁预防
2)死锁避免
3)死锁的检测于解除
几种策略的比较:
在这里插入图片描述

2.4.3死锁的预防

破坏四个必要条件之一即可
1)破坏互斥
不太可行,并且有的场合需要保护这种互斥性
2)破坏不可剥夺条件
这种方法常用于易于保护和恢复的资源,如CPU的寄存器及内存资源,一般不能用于打印机之类的资源
3)破坏请求和保持条件
采用静态分配方法,一次申请所有需要资源,资源不足,不运行。一旦运行,资源一直归他所有。资源浪费严重,容易“饥饿”。
4)破坏循环等待条件
采用资源顺序分配法可实现。

2.4.4死锁避免

在资源动态分配过程时,防止系统进入不安全状态,以避免死锁发生

1.系统安全状态

所谓安全状态,是指系统按照某种进程推进顺序(P1、P2..Pn),为每个进程分配所需资源,直到满足进程对资源的最大需求,使每个进程都可顺利完成任务。此时P1、P2..Pn为安全序列。如果无法找到一个安全序列,则系统处于不安全状态
说明:不安全状态不一定死锁,但系统若处于安全状态,便可以避免死锁。

2.银行家算法——避免死锁的典型算法

在这里插入图片描述

2.4.5死锁的检测和解除

1.资源分配图

2.死锁定理

系统状态S死锁的条件是当且仅当S状态的资源分配图是不可完全化简的,该条件为死锁定理

3.死锁解除

1)资源剥夺法
2)撤销进程法
3)进程回退法

持续更新中ing!!!

猜你喜欢

转载自blog.csdn.net/qq_41317652/article/details/84594237