操作系统整理-第二章-进程管理

一、进程与线程

1.1 进程的概念与特征

  1. 进程的概念
    为了更好的控制程序之间的并发执行,OS引入了进程的概念。
    进程又称进程映像的运行过程,进程映像包含程序段、相关数据、PCB。
    PCB(Process Control Block,进程控制块)是一个描述进程基本情况和运行状态的数据结构。
    PCB是进程存在的唯一标志,OS分配资源和调度的唯一单位。创建进程就是创建进程中的PCB,撤销进程就是撤销进程中的PCB。
  1. 进程的特征
    a)动态性:进程是进程映像一次运行过程,有着自己的生命周期,动态的产生、变化、消亡。
    b)并发性:多个进程映像(进程实体)存入内存之中,并发的执行,以提高资源利用率。
    c)独立性:进程是独立运行、独立获取资源、独立接受调度的基本单位。
    d)异步性:由于进程相互制约,会使得进程具有制约性,各个进程走走停停,以不可预知的速度向前推进。异步性会导致执行结果的不可再现性,为此OS要配备进程同步机制,让进程之间有合理的前后运行关系。
    e)结构性:进程是进程实体运行的过程,而进程实体是由程序段、数据段、进程控制块三部分组成。

1.2 进程的状态与转换

进程是一个动态的过程,就自然有不同的状态。
1)创建态:申请PCB,向其填一些控制信息和管理信息,然后分配能运行所需要的前置资源,然后就将进程转换为就绪态
2)就绪态:进程获得了除处理机外的一切所需资源,然后排在就绪队列后面,等待获取处理机。
3)运行态:就绪队列拿出就绪进程,让其在处理机上运行,运行结束则转到结束态,若是进程时间片用完则将进程转化为就绪态。在单核CPU中,每一时刻只有一个进程处于运行态。
4)阻塞态:当一个进程在运行过程中想获取其它资源如I/O,进程暂停,让出CPU,将自己阻塞,当其获得了除CPU之外的一切资源时,又转为就绪态。
5)结束态:正常结束或其它原因中断退出运行,OS先将进程状态置为结束态,然后再进一步处理资源释放和回收等工作。
在这里插入图片描述

1.3 进程控制

进程控制的代码是原语,不允许中断。进程控制主要是进程的创建、进程的撤销、实现进程之间的转换。

  1. 进程的创建
    子进程与父进程的关系:父进程可以创建一个子进程,子进程可以继承父进程的所有资源。当子进程撤销时,将其所用的资源归还给父进程,而父进程撤销时,要将子进程一起撤销。
    创建一个新的进程4步骤如下:
    1)分配唯一的进程标识号,申请PCB(PCB是有限的,所以可能申请失败)
    2)为进程分配除CPU之外的资源,分配程序、数据、用户栈所需的内存资源。
    注:资源不足时,进程不会创建失败,而是处于等待资源的状态。
    3)初始化PCB
    4)若进程就绪队列未满,则将其插入就绪队列。
  1. 进程的终止
    进程结束情况:正常结束、异常结束、外界干预。
    OS终止进程有5步:
    1)根据终止进程标识符,检索PCB,从中读取该进程的状态。
    2)若此时发现该进程处于执行状态,则马上终止,让出CPU。
    3)若此时发现该进程有子进程,马上终止。
    4)把该进程所拥有的资源归还给父进程或者OS。
    5)将该PCB从所在数据结构中删除。
  1. 进程的阻塞和唤醒
    正在执行的进程,若请求系统其它资源失败、等待某种操作的完成、新数据尚未到达或无新工作可做等,由系统自动执行阻塞原语(Block),使自己从运行态转变成阻塞态。阻塞原语执行过程如下3步:
    1)根据标识号找PCB
    2)若该进程在运行,则保护现场,然后转为阻塞态。
    3)将该PCB插入等待事件相应的数据结构,然后让出CPU。
    唤醒原语如下三步:
    1)从该事件的等待队列找到PCB。
    2)移除该PCB,将其转为就绪态。
    3)将该PCB插入就绪队列,等待CPU的调度。
    Block原语与Wakeup原语是一对相反操作,Block原语由阻塞进程自己调用的,而Wakeup原语是由一个与被唤醒进程合作或被其它相关的进程调用实现的。
  1. 进程切换
    进程切换和上面的其它操作都是在操作系统内核的支持下运行的。
    进程切换时指处理机从一个进程的运行转到另一个进程上运行。切换过程如下6步:
    1)保存处理机上下文,包括程序计数器和其它寄存器。
    2)更新PCB信息
    3)把进程的PCB移入就绪或是阻塞队列。
    4)选择另一个进程执行,并更新其PCB。
    5)更新内存管理的数据结构
    6)恢复处理机上下文。

1.4 进程的组织

进程是进程映像运行的过程,进程映像由程序段、数据段、PCB组成。

  1. 进程控制块PCB
    建立好PCB之后,该结构常驻内存,是进程存在的唯一标志。
进程描述信息进程控制和管理信息资源分配清单处理机相关信息
进程标识符(PID)进程当前状态代码段指针通用寄存器值
用户标识符(UID)进程优先级数据段指针地址寄存器址
代码运行入口地址堆栈段指针控制寄存器值
程序的外存地址文件描述符标注寄存器值
进入内存时间键盘状态字
处理机占用时间鼠标
信号量使用

1.5 进程的通信

进程通信是指进程之间的信息交换,通过这种信息交换以达到进程之间的相互合作。通信分为两类:
1)PV操作,低级通信方式。
2)较高的效率传输大量数据的通信方式,高级通信方式,有如下3种。

  1. 共享存储
    进程空间都是相互独立的,不能直接访问其它进程空间中的信息。此时系统给出一块空间,各个进程通过对上面的数据进行读写来实现通信。此时需要用到互斥机制来保证数据的正确性。
    注:共享空间可以是共享的数据结构,也可以是基于存储区的共享。
  1. 消息传递
    系统定义一个消息格式Message,并提供发送消息和接收消息两个原语进行数据交换。而这种通信分为两种如下:
    1)直接通信方式:发送进程把发的消息直接挂在接收进程的消息缓冲队列上,接收进程从消息缓冲队列中取得消息。
    2)间接通信方式:发送进程把消息发送到某个中间实体,接受进程从中间实体取得消息。我们也称中间实体为信箱。
  1. 管道通信
    用一个文件来连接读进程和写进程,方便它们以字符流形式大量传输信息。我们又称管道为pipe文件。pipe文件与普通的文件的区别是:
    1)限制管道大小。不会像文件那样不加检验的增长。当写满时,write()将调用阻塞原语阻塞自己。
    2)读进程也可能工作得比写进程快,当读空是,read()将阻塞自己,而不是像文件那样返回文件结束的问题。
    注:管道算法共享存储的发展,它可以一边读一边写,只是当满或没的时候有相应的阻塞。这也决定管道是半双工通信。

1.6线程概念和多线程模型

  1. 线程的基本概念
    线程最直接的理解就是“轻量级进程”,它不拥有系统资源,但是CPU执行的基本单元。它的出现是为了减小程序在并发执行时所付出的时空开销,提高操作系统的并发性能。
    线程由线程ID、程序计数器、寄存器集合和堆栈组成。切换的两个线程如果来自同一个进程,则只需要很少的时空开销。
  1. 线程与进程的比较
    1)调度与拥有资源
    线程是独立调度的基本单位,进程是拥有资源的基本单位。
    2)并发性
    不仅进程之间可以执行并发,而且多个线程之间也可以执行并发,从而使操作系统具有更好的并发性,提高了系统的吞吐量。
    3)系统开销
    进程创建等的开销大于线程,进程切换的开销比同一进程中线程切换的开销大。进程通信的开销比同一进程中多个线程通信的开销大。
    4)地址空间和其它资源
    进程的地址空间之间相互独立,同一进程的各线程间共享进程的资源,某进程内的线程对于其它进程不可见。
  1. 线程的属性
    1)线程是一个轻型实体,它不拥有系统资源,每一个线程有一个线程控制块。
    2)不同线程可以执行相同的程序,即同一个服务程序被不同的用户调用时,OS创建不同的线程。
    3)同一进程的各线程共享该进程所有资源。
    4)CPU的执行单位。
    5)线程跟进程一样,有自己的生命周期,在其期间也有各种状态的转换。
  1. 线程的实现方式
    线程分为内核级线程(内核支持的线程)和用户级线程。
    1)用户级线程的各种操作由代码实现(用线程库区派生线程),内核感受不到这些线程的存在。
    2)内核级线程的各种操作由内核完成
    在这里插入图片描述
  1. 多线程模型
    1)多对一模型:将多个用户级线程映射到一个内核级线程,线程管理在用户空间完成。
    2)一对一模型:将每个用户级线程映射到一个内核级线程。
    3)多对多模型:将n个用户级线程映射到m个内核级线程上,m<=n

二、处理机调度

2.1 调度的概念

  1. 调度的基本概念
    有多个进程争夺一个CPU,如何让它们有序的并发,就要按照一定的算法(公平、高效)选择进程执行的顺序来让CPU执行,保证系统的并发和利用率。这是多道程序设计的基础,也是操作系统的核心。
  1. 调度的层次
    1)作业调度
    又称高级调度,主要就是按照一定的原则将外存上处于后备状态的作业中,给它们分配资源,让它们有资格去争夺CPU。
    2)中级调度
    又称内存调度,其作用是提高内存利用率,把暂时不能运行的作业掉至外存外,将其挂起。
    3)进程调度
    按照一定规则,把CPU分配给其它进程。进程调度的频率极高。
  1. 三级调度的联系
    1)作业调度为进程活动做准备,进程调度使进程正常活动起来,中级调度将暂时不能运行的程序挂起。
    2)作业调度次数少,中级调度略多,进程调度频率最高。
    3)进程调度是最基本的,不可或缺。

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

  1. 不能进行进程的调度与切换的情况
    1)在处理中断过程中
    2)进程在操作系统内核程序临界区中
  2. 应该进行进程切换的情况
    1)发生引起调度条件且当前进程无法继续运行下去是。
    2)中断处理结束或自陷处理结束后,恢复原来进程的执行现场,根据PC来继续执行。

2.3 进程调度方式

1)非剥夺调度方式,非抢占方式,除非自己让出CPU,否则别想。
2)剥夺调度方式,除了自己可以把CPU让出来,系统可以决定是否把CPU让出来。

2.4 调度的基本准则

1)CPU利用率
CPU是计算机中最昂贵的资源,要让CPU“忙起来”。
2)系统吞吐量
单位时间内CPU完成作业的数量
3)周转时间
周转时间=作业完成时间-作业提交时间
4)等待时间
进程等待处理机状态的时间之和。
5)响应时间
用户从提交作业到系统首次响应所用的时间。

2.5 典型的调度算法

为了满足以上的准则,以下介绍一些经典的调度算法。

  1. 先来先服务(FCFS)调度算法
    算法实现简单,对长作业有利,有利于CPU繁忙型作业,不利于I/O繁忙性作业。效率低
  2. 短作业优先(SJF)调度算法
    根据FCFS对短作业长时间无法响应的缺点,提出SJF。但是SJF会导致长作业长时间得不到执行,甚至直接“饿死”。第二个就是没有考虑作业的时间紧迫度。
  3. 优先级调度算法
    按照不同的标准可以分为
    1)非剥夺式优先级调度算法2)剥夺式
    1)静态优先级2)动态优先级
    优先级的设置可以按照如下原则
    1)系统进程>用户进程2)交互型进程>非交互型进程3)I/O型进程>计算型进程
  4. 高响应比优先调度算法
    结合上面的优缺点,考虑到短作业,又考虑到长作业不会“饥饿”。
    响应比=(等待时间+要求服务时间)/ 要求服务时间
  5. 时间片轮转调度算法
    顾名思义,每个进程分配一个时间片,用完就把CPU分配给另一个进程。
  6. 多级反馈队列调度算法
    时间片轮转法和优先级调度算法的综合发展,动态的调整时间片和优先级。
    思想如下
    1)设置多个就绪队列,每个队列的优先级逐渐降低
    2)每个队列的时间片大小各不相同
    3)第一队列的进程时间片用完之后就放在下一队列,如此循环。
    4)只有当前面的所有队列的进程的时间片都用完了,才能进行下面队列中进程的执行。

三、进程同步

3.1 进程同步的基本概念

1+23=?对于这个问题,计算机先算(1+2)这个进程,还是先算(23)这个进程?这里就有一个执行的先后顺序,这就要考虑到进程之间的同步问题。

  1. 临界资源
    很多进程想同时访问的资源就叫临界资源。对于临界资源的访问,就必须互斥的进行,在每个进程中,访问临界资源的那段代码称为临界区。为了保证临界资源的正确使用,可把临界资源的访问过程分成4个部分:
    1)进入区:检查是否可进入,设置标志防止其它进程进入临界区
    2)临界区:进程中访问临界资源的那段代码,又称临界段。
    3)退出区:将正在访问临界区的标志清除
    4)剩余区:代码中的其它部分
  1. 同步
    又称其为直接制约关系,它们需要相互协调。
  2. 互斥
    互斥也称间接制约关系,当一个进程进入临界区域时,另一个进程必须等待。为禁止两个进程同时进入临界区,同步机制应遵循以下准则:
    1)空闲让进
    2)忙则等待
    3)有限等待
    4)让权等待
    :后面所讲的内容都是围绕着这四个标准去发展演进的。

3.2 实现临界区互斥的基本方法

  1. 软件实现方法
    核心思想为设置标志来代表临界区的资源是否正在被访问。
    1)单标志法
P0进程
while(turn != 0);//进入区
critical section;//临界区
turn = 1;//退出区
remainder section;//剩余区
P1进程
while(turn != 1);
critical section;
turn = 0;
remainder section;

算法一违背了“空闲让进”
2)双标志法先检查

Pi进程
while(flag[j]);第一步
flag[i] = TRUE;第三步
critical section;
flag[i] = FALSE;
remainder section;
Pj进程
while(flag[i]);第二步
flag[j] = TRUE;第四步
critical section;
flag[j] = FALSE;
remainder section;

若上面按照第一二三四步完成,则会违背“忙则等待”。
3)双标志法后检查

Pi进程
flag[i] = TRUE;
while(falg[j]);
critical section;
flag[i] = FALSE;
remainder section;
Pj进程
flag[j] = TRUE;
while(falg[i]);
critical section;
flag[j] = FALSE;
remainder section;

可能出现相互谦让,导致谁也进入不了临界区,导致“饥饿”现象。
4)Peterson’s Algorithm

Pi进程
flag[i] = TRUE;turn = j;
while(falg[j] && turn == j);
critical section;
flag[i] = FALSE;
remainder section;
Pj进程
flag[j] = TRUE;turn = i;
while(falg[i] && turn ==i);
critical section;
flag[j] = FALSE;
remainder section;
  1. 硬件实现方法
    1)中断屏蔽方法
    关中断;临界区;开中断;
    2)硬件指令方法
    a)TestAndSet指令:原子操作。
boolean TestAndSet(boolean *lock){
	boolean old;
	old = *lock;
	*lock = true;
	return old;
}
while TesAndSet(&lock);
进程的临界区代码段;
lock = FALSE;
进程的其它代码;

b)Swap指令:该指令的功能是交换两个字的内容

Swap(boolean *a,boolean *b){
	boolean temp;
	temp = *a;
	*a = *b;
	*b = temp;
}

注:它们是由硬件逻辑实现,不会被中断,上面的代码只是描述其功能。

3.3 信号量

  1. 整型信号量
    把资源数目用一个整型变量S表示,wait和signal操作描述如下:
//wait()操作我们称其为P操作
//signal()操作我们称其为V操作
wait(S){
	while(S<=0);
	S = S - 1;
}
signal(S){
	S = S + 1;
}

注:当S<0时,wait操作一直反复测试,没有遵循“让权等待”。
2. 记录型信号量
在上面的基础上增加一个进程链表L,实现让权等待,将等待的进程插入进程链表L。

typedef struct{
	int value;
	struct process *L;
}semaphore;
void wait(semaphore S){
	S.value--;
	if(S.value < 0){//这里用的就不是while()
	add this process to S.L;
	block(S.L);//通过自我阻塞来实现让权等待
	}
}
void signal(semaphore){
	S.value++;
	if(S.value <= 0){
		remove a process P from S.L;
		wakeup(P);
	}
}
  1. 利用信号量实现同步
semaphore S = 0;//设为0是因为这是同步而不是互斥,P2进程一开始就不能操作x,必须先让P1完成。
P1(){
	do(x);
	V(S);
}
P2(){
	P(S);
	do(x);
}
//注:自己的阻塞与别人的唤醒
  1. 利用信号量实现进程互斥
semaphore S = 1//初始化信号量为1,这个时候是去多个进程去抢。
P1(){
	P(S);
	进程P1的临界区;
	V(S);
}
P2(){
	P(S);
	进程P2的临界区;
	V(S)
}
  1. 利用信号量实现前驱关系
    有同步的地方就设置一个记录型信号量,前驱关系就通过同步的方式表达出来。

3.4 管程

在上面的信号量机制中,要访问临界资源的进程都必须自备同步的PV操作,大量分散的同步操作给系统带来了麻烦,而且容易因同步操作不当带来死锁,此时系统提供一种类似P V操作的方法来实现互斥,我们称其为管程。

  1. 管程的定义
    它统一管理了各类资源,用少量的信息来表示资源,我们称为对资源定义的数据结构,在这组数据结构上定义一组操作来实现互斥。数据结构加这组操作就叫管程。
    特点
    1)管程把对共享资源的操作封装起来,想类一样。
    2)每次仅允许一个进程进入管程,从而实现进程互斥。
  2. 条件变量
    当一个进程进入管程,但是它又要申请其它共享资源,此时它并不释放管程。而当这个时候,应该把该进程阻塞,所以设置条件变量condition,当因为一种条件阻塞时,就将其插入该条件而阻塞的队列里。

3.5 经典同步问题

  1. 生产者-消费者问题:缓冲区是临界资源
  2. 读者-写者问题:运行读读,但是不允许读写,写写同时进行。
  3. 哲学家进餐问题:n个人,每个人旁边有一根筷子,一共n个,如果每个人都拿起一个筷子,则大家都吃不成饭。
  4. 吸烟者问题:同步+互斥问题
    详细解答

四、死锁

4.1 死锁的概念

  1. 死锁的定义
    一条单行道,两边都有小轿车,一个想过去,一个想过来。现实生活中的死锁。
    计算机中,进程P1获取资源1并保持资源1,进程P2获取资源2并保存资源1,此时P1请求资源2,P2请求资源1。
  2. 死锁产生的原因
    1)系统资源竞争且不可剥夺
    2)进程推荐顺序非法
    3)信号量使用不当也会造成死锁
  3. 死锁产生的必要条件
    1)互斥条件
    2)不剥夺条件
    3)请求并保存条件
    4)循环等待条件
    注:这四个条件必须同时满足才会产生死锁,所以死锁预防和解除也是靠这四个。

4.2 死锁的处理策略

破坏死锁产生的四个必要条件,或允许产生死锁,然后再去解除。

  1. 死锁预防
    破坏四个条件之一
  2. 避免死锁
    用算法防止系统进入不安全状态,来避免死锁,不安全状态就是进程无论怎么分配资源,如果不发生其它进程终止的情况,一定会导致死锁。
  3. 死锁的检测及解除
    允许发生死锁,然后采取措施解除死锁。
    注:死锁预防实现简单,但是利用率低。而避免死锁需要用算法来判断系统是否进入不安全状态,实现起来较为复杂。

在这里插入图片描述

4.3 死锁预防

防止死锁的发生只需要破坏死锁产生的4个必要条件之一即可。

  1. 破坏户次条件:不太可行
  2. 破坏不剥夺条件:保存CPU现场即可,一般不能用于打印机之类的资源。
  3. 破坏请求并保存条件:一次性申请完要使用的全部资源,这样实现起来简单,但效率极低。
  4. 破坏循环等待条件:首先给系统中的资源编号,规定每一个进程必须按编号递增的顺序请求资源,同类资源一次性申请完

4.4 死锁避免

  1. 系统安全状态
    在保证资源都能分配够的情况下预先找出一种进程推进的序列,若能找到,就认为系统处于安全状态,否则系统处于不安全状态。
  2. 银行家算法(资源就像钱,申请资源就像贷款一样,系统就是银行家)
    进程先申明自己对某个共享资源最大需求量是多少(声明这个的原因是好提前判断系统是否处于安全状态),当进程申请某类资源时,判断自己已拥有资源+想申请资源是否大于最大需求资源(针对一种共享资源)。若大于直接拒绝,否则判断系统如果分配了该资源,此时的系统是否处于安全状态,若处于则分配,否则也要推迟分配。
    1)数据结构描述
    a)可利用资源Available[j] = K表示系统中有Rj类资源K个
    b)最大需求矩阵Max:nxm矩阵,n个进程,m类资源。Max[i,j]=K表示进程i需要Rj类资源的最大数目为K。
    c)分配矩阵Allocation:nxm矩阵,Allocation[i,j]=K表示进程 i 当前已分得Rj类资源的数目为K。
    d)需求矩阵Need:nxm矩阵Need[i,j]=K表示进程 i 还需要Rj类资源的数目为K
    2)银行家算法描述
    若进程请求某类资源,先分配,再判断系统是否处于安全状态,若处于,则实际分配给该进程,否则撤销分配。
    3)安全性算法
    用Available向量去匹配Need矩阵,若资源够就分配,然后加上Allocation矩阵,循环上面继续去匹配,直到所有进程都进入一个安全序列,则系统是安全的。否则不安全。
  1. 银行家算法举例
    详细例子

4.5 死锁检测和解除

  1. 资源分配图
    在这里插入图片描述
    长方形代表一类资源,小圆圈代表该资源的个数。
  1. 死锁定理
    简化资源分配图,找出既不阻塞又不孤点的进程,然后去掉它的边,循环前面的步骤,若资源分配图能够被完全简化,则不会有死锁。
    有死锁的条件是当且仅当此时刻的资源分配图是不可完全简化的,该条件为死锁定理。
  2. 死锁解除
    1)资源剥夺法:需注意防止被挂起的进程长时间得不到资源而处于资源匮乏状态。
    2)撤销进程法:撤销到进程可以推进为止,撤销可以按照进程的优先级和撤销所需要的代价大小来进行。
    3)进程回退法:让一个或多个进程回退到组一回避死锁的地步,进程回退时自愿释放资源而非被剥夺。要求系统保持进程的历史信息,设置还原点。
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值