操作系统笔记二(进程管理:进程实体、进程状态、进程同步、进程调度、死锁)

1.进程基本概念

进程是系统进行资源分配和调度的基本单位
进程作为程序独立运行的载体保障程序正常执行。
进程的存在使得操作系统资源的利用率大幅提升。

2.进程的实体

2.1主存中的进程形态

在主存中进程是一段连续的存储空间,我们把这段空间称为进程控制块。进程控制块里面包含了:标识符、状态、优先级、程序计数器、内存指针、上下文数据、IO状态信息、记账信息等等
标识符:唯一标记一个进程,用于区别其他进程。
状态:标记进程的进程状态,如:运行态。
程序计数器:进程即将被执行的下一条指令的地址。
内存指针:程序代码,进程数据相关指针。
上下文数据:进程执行时处理器存储的数据。
IO状态信息:被进程IO操作所占用的文件列表。
记账信息:使用处理器时间、时钟数总和等。

那么什么是进程控制块(PCB)呢?
用于描述和控制进程运行的通用数据结构;记录进程当前状态和控制进程运行的全部信息;PCB使得进程是能给个独立运行的基本单位。个人理解进程与PCB的关系就相当于数据与数据结构的关系。

2.2进程与线程

线程是操作系统进行运行调度的最小单位线程包含在进程中是进程中实际运行工作的单位一个进程可以并发多个线程,每个线程执行不同的任务。进程的线程共享进程的资源

3.进程管理之五状态模型

在这里插入图片描述

新建态:对应于进程被创建时的状态,尚未进入就绪队列。
创建一个进程需要通过两个步骤:
1>为新进程分配所需要资源和建立必要的管理信息。
2>设置该进程为就绪态,并等待被调度执行。

终止态:指进程完成任务到达正常结束点,或出现无法克服的错误而异常终止,或被操作系统及有终止权的进程所终止时所处的状态。
处于终止态的进程不再被调度执行,下一步将被系统撤销,最终从系统中消失。

终止一个进程需要两个步骤:
1>先等待操作系统或相关的进程进行善后处理(如抽取信息)。
2>然后回收占用的资源并被系统删除。

运行(running)态:进程占有处理器正在运行的状态。
进程已获得CPU,其程序正在执行。在单处理机系统中,只有一个进程处于执行状态; 在多处理机系统中,则有多个进程处于执行状态。

就绪(ready)态:进程具备运行条件,等待系统分配处理器以便运行的状态。
当进程已分配到除CPU以外的所有必要资源后,只要再获得CPU,便可立即执行,进程这时的状态称为就绪状态。在一个系统中处于就绪状态的进程可能有多个,通常将它们排成一个队列,称为就绪队列

等待(wait)态:又称阻塞态或睡眠态,指进程不具备运行条件,正在等待某个时间完成的状态。
也称为等待或睡眠状态,一个进程正在等待某一事件发生(例如请求I/O而等待I/O完成等)而暂时停止运行,这时即使把处理机分配给进程也无法运行,故称该进程处于阻塞状态。

4.进程间的同步

4.1什么是进程同步?

进程同步的概念:把异步环境下的一组并发进程因直接制约而互相发送消息、进行互相合作、互相等待,使得各进程按一定的速度执行的过程称为进程间的同步

4.2为什么需要进程间同步?

①生产者消费者问题
生产者消费者问题(英语:Producer-consumer problem),也称有限缓冲问题(英语:Bounded-buffer problem),是一个多线程同步问题的经典案例。该问题描述了共享固定大小缓冲区的两个线程——即所谓的“生产者”和“消费者”——在实际运行时会发生的问题。生产者的主要作用是生成一定量的数据放到缓冲区中,然后重复此过程。与此同时,消费者也在缓冲区消耗这些数据。该问题的关键就是要保证生产者不会在缓冲区满时加入数据,消费者也不会在缓冲区中空时消耗数据。

要解决该问题,就必须让生产者在缓冲区满时休眠(要么干脆就放弃数据),等到下次消费者消耗缓冲区中的数据的时候,生产者才能被唤醒,开始往缓冲区添加数据。同样,也可以让消费者在缓冲区空时进入休眠,等到生产者往缓冲区添加数据之后,再唤醒消费者。通常采用进程间通信的方法解决该问题。如果解决方法不够完善,则容易出现死锁的情况。出现死锁时,两个线程都会陷入休眠,等待对方唤醒自己。该问题也能被推广到多个生产者和消费者的情形。
在这里插入图片描述
要注意的三点:
其一:在缓冲区为空时,消费者不能再进行消费
其二:在缓冲区为满时,生产者不能再进行生产
其三:在一个线程进行生产或消费时,其余线程不能再进行生产或消费等操作,即保持线程间的同步

前两点都好理解,第三点解释一下,生产\消费过程分三步,首先 把仓库中的数据赋值给计数器,生产完计数器加一,最后把计数器值赋值给仓库数据。倘若生产过程中又出现消费,生产到第二步,生产者计数已经加一,仓库数据不变(假设为10),此时消费者开始消费,当消费者消费完,仓库数据应该减一(此时为9),最后生产者继续完成剩下步骤,将已经加一的计数赋值给仓库数据(结果为11)。这显然不对。

②哲学家进餐问题
有五个哲学家,他们的生活方式是交替地进行思考和进餐。他们共用一张圆桌,分别坐在五张椅子上。在圆桌上有五个碗和五支筷子,平时一个哲学家进行思考,饥饿时便试图取用其左、右最靠近他的筷子,只有在他拿到两支筷子时才能进餐。进餐完毕,放下筷子又继续思考。显然,无论是都拿左边还是右边依旧无法进餐。

问题根源:进程间没有通信,生产者没有告诉消费者已经生产了一个零件,哲学家也没有告诉相邻两人要进餐要两个筷子。

4.3进程同步解决的问题:

其一:对竞争资源在多进程间进行使用次序的协调。比如哲学家,可以先让不相邻的两人先吃。
其二:使得并发执行的多个进程之间可以有效使用资源和相互合作。

4.4进程间同步的原则

临界资源:指的是一些虽然作为共享资源却又无法同时被多个线程共同访问的共享资源。当有进程在使用临界资源时,其他进程必须依据操作系统的同步机制等待占用进程释放该共享资源才可以重新竞争使用的共享资源。

进程间同步的原则有四个:
1>空闲让进:资源无占用,允许使用
2>忙则等待:资源有占用,请求进程等待
3>有限等待:保证在有限等待时间内能够使用到资源
4>让权等待:等待时,进程需要让出CPU

进程间同步的一些方法:消息队列、共享存储、信号量

4.5线程同步

进程内的多线程也需要同步,因为多线程并发使用资源时也会发生上述进程出现的问题。

线程同步的方法:互斥量、读写锁、自旋锁、条件变量

5.进程调度

5.1基本概念

作业是用户向计算机提交任务的任务实体。一个作业可由多个进程组成,且必须至少由一个进程组成,反过来则不成立。作业的概念主要用在批处理系统中。
进程调度是指计算机通过决策决定哪个就绪进程可以获得CPU的使用权。

5.2进程调度的步骤:

首先,保留旧进程的运行信息,请出旧进程(收拾包袱)
最后,选择新进程,准备运行环境并分配CPU(新进驻)

5.3进程调度的三种机制

其一:就绪队列的排队机制
将就绪进程按照一定的方式排成队列,以便调度程序可以最快找到就绪进程。
其二:选择运行进程的委派机制
调度程序以一定的策略选择就绪进程,将CPU资源分配给它。
其三:新老进程的上下文切换机制
当前任务在执行完 CPU 时间片切换到另一个任务之前会先保存自己的状态,以便下次再切换回这个任务时,可以再加载这个任务的状态。任务从保存到再加载的过程就是一次上下文切换
保存当前进程的上下文信息,装入被委派执行进程的运行上下文。

新老进程切换的两种情况
非抢占式调度
处理器一旦分配给某个进程,就让该进程一直使用下去,调度程序不以任何原因抢占正在被使用的处理器,直到进程完成工作或因为IO阻塞才会让出处理器。
抢占式调度
允许调度程序以一定的策略暂停当前运行的进程,保持好旧进程的上下文信息,分配处理器给新进程。
在这里插入图片描述

5.4进程调度的四种算法

先来先服务调度算法:先来先服务调度算法是一种最简单的调度算法,也称为先进先出或严格排队方案。当每个进程就绪后,它加入就绪队列。当前正运行的进程停止执行,选择在就绪队列中存在时间最长的进程运行。该算法既可以用于作业调度,也可以用于进程调度。先来先去服务比较适合于长作业(进程),而不利于短作业(进程)。

短作业优先调度算法:短作业优先调度算法是指对短作业优先调度的算法,从后备队列中选择一个或若干个估计运行时间最短的作业,将它们调入内存运行。 短作业优先调度算法是一个非抢占策略,他的原则是下一次选择预计处理时间最短的进程,因此短进程将会越过长作业,跳至队列头。

高优先权优先调度算法:该算法是对先来先服务调度算法和短作业优先调度算法的一种综合平衡,同时考虑每个作业的等待时间和估计的运行时间。在每次进行作业调度时,先计算后备作业队列中每个作业的响应比,从中选出响应比最高的作业投入运行。

时间片轮转调度算法:时间片轮转调度算法主要适用于分时系统。在这种算法中,系统将所有就绪进程按到达时间的先后次序排成一个队列,进程调度程序总是选择就绪队列中第一个进程执行,即先来先服务的原则,但仅能运行一个时间片。

6.死锁

6.1基本概念

死锁是指两个或者两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。

6.2死锁的产生

其一:竞争资源
共享资源数量不满足各个进程需求,各个进程之间发生资源进程导致死锁。
例如:进程1与进程2都需要资源1与资源2,但进程1只有资源1,进程2只有资源2,结果都无法正常运行。倘若资源1与资源2无论哪个再多出一个就不会出现死锁。
其二:进程调度顺序不当
其实个人感觉还是与第一种一样。例如进程1先拥有资源1,然后进程2拥有了资源2,进程1又无法拥有资源2,进程2也无法拥有资源1,倘若进程1先拥有资源1,然后接着让进程1拥有资源2,等进程1执行完,释放资源后,再由进程2执行,就不会出现死锁。

死锁的四个必要条件(只要产生死锁四个都存在)
互斥条件:进程要求对所分配的资源进行排它性控制,即在一段时间内某资源仅为一进程所占用。
请求和保持条件:当进程因请求资源而阻塞时,对已获得的资源保持不放。
不剥夺条件:进程已获得的资源在未使用完之前,不能剥夺,只能在使用完时由自己释放。
环路等待条件:在发生死锁时,必然存在一个进程–资源的环形链。

6.3死锁的处理

其一:预防死锁的方法
其实上面四个必要条件破坏任意一个或者多个即可。
资源一次性分配:一次性分配所有资源,这样就不会再有请求了(破坏请求和保持条件
只要有一个资源得不到分配,也不给这个进程分配其他的资源(破坏互斥条件
可剥夺资源:即当某进程获得了部分资源,但得不到其它资源,则释放已占有的资源(破坏不可剥夺条件
资源有序分配法:系统给每类资源赋予一个编号,每一个进程按编号递增的顺序请求资源,释放则相反(破坏环路等待条件

其二:避免死锁——银行家算法
银行家算法是一个可操作的著名的避免死锁的算法。这是一个基于银行贷款的算法,客户申请的贷款是有限的,每次申请需要声明最大资金量。银行家在能够满足贷款时,都应该给用户贷款。客户在使用贷款后,能够及时归还贷款。

银行家算法有四个数据结构
为了实现银行家算法,在系统中必须设置这样四个数据结构,分别用来描述系统中可利用的资源、所有进程对资源的最大需求、系统中的资源分配,以及所有进程还需要多少资源的情况。
  (1) 可利用资源向量 Available。这是一个含有 m 个元素的数组,其中的每一个元素代表一类可利用的资源数目,其初始值是系统中所配置的该类全部可用资源的数目,其数值随该类资源的分配和回收而动态地改变。如果 Available[j] = K,则表示系统中现Rj类资源K个。
  (2) 最大需求矩阵Max。这是一个n x m的矩阵,它定义了系统中n个进程中的每个进程对m类资源的最大需求。如果Max[i,j] = K,则表示进程i需要Rj 类资源的最大数目为K。
  (3) 分配矩阵 Allocation。这也是一个n x m的矩阵,它定义了系统中每一类资源当前已分配给每一进程的资源数。如果 Allocation[i,jl = K,则表示进程i当前己分得Rj类资源的数目为K。
  (4) 需求矩阵Need.这也是一个n×m的矩阵,用以表示每一个进程尚需的各类资源数。如果Need[i,j] = K,则表示进程i还需要Rj类资源K个方能完成其任务。
上述三个矩阵间存在下述关系(需求=最大需求-已分配):
              Need[i,j] = Max[i,j] - Allocation[i, j]
              
银行家算法详述:
  设 Request;是进程Pi的请求向量,如果 Requesti[j] = K,表示进程Pi需要K个Rj类型的资源。当Pi发出资源请求后,系统按下述步骤进行检査:
  (1) 如果 Requesti[j] ≤ Need[i,j]便转向步骤(2);否则认为出错,因为它所需要的资源数已超过它所宣布的最大值。
  (2) 如果 Requesti[j] ≤ Available[j],便转向步骤(3);否则,表示尚无足够资源,Pi须等待。
  (3) 系统试探着把资源分配给进程Pi,并修改下面数据结构中的数值
    Available[j] = Available[j] - Requesti[j];
    Allocation[i,j] = Allocation[i,j] + Requesti[j];
    Need[i,j] = Need[i,j] - Requesti[j];
  (4) 系统执行安全性算法,检查此次资源分配后系统是否处于安全状态。若安全,才正式将资源分配给进程Pi,以完成本次分配;否则,将本次的试探分配作废,恢复原来的资源分配状态,让进程Pi等待。

安全性算法:
系统所执行的安全性算法可描述如下:
  (1) 设置两个向量:①工作向量Work,它表示系统可提供给进程继续运行所需的各类资源数目,它含有m个元素,在执行安全算法开始时,Work = Available;② Finish:它表示系统是否有足够的资源分配给进程,使之运行完成。开始时先做 Finish[i] = false;当有足够资源分配给进程时,再令Finish[i] = true。
  (2) 从进程集合中找到一个能满足下述条件的进程
    ① Finish[i] = false;
    ② Need[i,j] ≤ Work[j];
若找到,执行步骤(3),否则,执行步骤(4)。
  (3)当进程Pi获得资源后,可顺利执行,直至完成,并释放出分配给它的资源,故应执行:
    Work[j] = Work[j] + Allocation[i,j];
    Finish[i] = true;
    go to step 2;(goto语句不推荐使用 _ )
  (4)如果所有进程的 Finish[i] =true都满足,则表示系统处于安全状态;否则,系统处于不安全状态。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值