目录
11.一般情况下在Linux/windows平台下栈空间的大小
1.进程与线程的区别和联系
- 进程是对运行时程序的封装,是系统进行资源调度和分配的的基本单位,实现了操作系统的并发;
- 线程是进程的子任务,是CPU调度和分派的基本单位,用于保证程序的 实时性,实现进程内部的并发;
- 一个程序至少有一个进程,一个进程至少有一个线程,线程依赖于进程而存在;
- 进程在执行过程中拥有独立的内存单元,而多个线程共享进程的内存。
2.进程、线程有哪几种状态
进程:
- 就绪状态:进程已获得除处理机以外的所需资源,等待分配处理机资源。
- 运行状态:占用处理机资源运行,处于此状态的进程数小于等于CPU数。
- 阻塞状态: 进程等待某种条件,在条件满足之前无法执行
线程:
在 Java虚拟机 中,线程从最初的创建到最终的消亡,要经历若干个状态:创建(new)、就绪(runnable/start)、运行(running)、阻塞(blocked)、等待(waiting)、时间等待(time waiting) 和 消亡(dead/terminated)。在给定的时间点上,一个线程只能处于一种状态,各状态的含义如下图所示:
3.一个进程可以创建多少线程,和什么有关
默认情况下,一个线程的栈要预留1M的内存空间,而一个进程中可用的内存空间只有2G,所以理论上一个进程中最多可以开2048个线程,但是内存当然不可能完全拿来作线程的栈,所以实际数目要比这个值要小。
如何突破2000个限制?
你也可以通过连接时修改默认栈大小,将其改的比较小,这样就可以多开一些线程。 如将默认栈的大小改成512K,这样理论上最多就可以开4096个线程。
即使物理内存再大,一个进程中可以起的线程总要受到2GB这个内存空间的限制。比方说你的机器装了64GB物理内存,但每个进程的内存空间还是4GB,其中用户态可用的还是2GB。
如果是同一台机器内的话,能起多少线程也是受内存限制的。每个线程对象都要站用非页面内存,而非页面内存也是有限的,当非页面内存被耗尽时,也就无法创建线程了。
如果物理内存非常大,同一台机器内可以跑的线程数目的限制值会越来越大。
4.一个程序从开始运行到结束的完整过程(四个过程)
- .c文件生成.obj文件的过程,称为编译,
- obj文件生成到.exe文件的过程,称为链接。
- .obj文件就是一个是程序编译生成的二进制文件,当.exe文件生成以后.obj文件就会被删除。
事实上,.c文件生成.exe文件的过程总共是经历了预处理,编译,汇编,链接,这四个过程。
5.进程通信方法
- 管道(pipe)及命名管道(named pipe):管道可用于具有亲缘关系的父子进程间的通信,有名管道除了具有管道所具有的功能外,它还允许无亲缘关系进程间的通信;
- 信号(signal):信号是一种比较复杂的通信方式,用于通知接收进程某个事件已经发生;
- 消息队列:消息队列是消息的链接表,它克服了上两种通信方式中信号量有限的缺点,具有写权限得进程可以按照一定得规则向消息队列中添加新信息;对消息队列有读权限得进程则可以从消息队列中读取信息;
- 共享内存:可以说这是最有用的进程间通信方式。它使得多个进程可以访问同一块内存空间,不同进程可以及时看到对方进程中对共享内存中数据得更新。这种方式需要依靠某种同步操作,如互斥锁和信号量等;
- 信号量:主要作为进程之间及同一种进程的不同线程之间得同步和互斥手段;
- 套接字:这是一种更为一般得进程间通信机制,它可用于网络中不同机器之间的进程间通信,应用非常广泛。
6.进程、线程同步的方式
线程:
原子操作、信号量机制、自旋锁管程、会合、分布式系统
进程:
- 互斥量 Synchronized/Lock:采用互斥对象机制,只有拥有互斥对象的线程才有访问公共资源的权限。因为互斥对象只有一个,所以可以保证公共资源不会被多个线程同时访问
- 信号量 Semphare:它允许同一时刻多个线程访问同一资源,但是需要控制同一时刻访问此资源的最大线程数量
- 事件(信号),Wait/Notify:通过通知操作的方式来保持多线程同步,还可以方便的实现多线程优先级的比较操作
7.怎么回收线程
线程分为可结合的(joinable)和 分离的(detached)两种,如果没有在创建线程时设置线程的属性,则线程默认是可结合的。
可结合的线程在线程退出后不会立即释放资源,必须要调用pthread_join来显式的结束线程。
分离的线程在线程退出时系统会自动回收资源。
8.分页和分段有什么区别(内存管理)
段式存储管理是一种符合用户视角的内存分配管理方案。在段式存储管理中,将程序的地址空间划分为若干段(segment),如代码段,数据段,堆栈段;这样每个进程有一个二维地址空间,相互独立,互不干扰。段式管理的优点是:没有内碎片(因为段大小可变,改变段大小来消除内碎片)。但段换入换出时,会产生外碎片(比如4k的段换5k的段,会产生1k的外碎片)
页式存储管理方案是一种用户视角内存与物理内存相分离的内存分配管理方案。在页式存储管理中,将程序的逻辑地址划分为固定大小的页(page),而物理内存划分为同样大小的帧,程序加载时,可以将任意一页放入内存中任意一个帧,这些帧不必连续,从而实现了离散分离。页式存储管理的优点是:没有外碎片(因为页的大小固定),但会产生内碎片(一个页可能填充不满)。
两者的不同点:
- 目的不同:分页是由于系统管理的需要而不是用户的需要,它是信息的物理单位;分段的目的是为了能更好地满足用户的需要,它是信息的逻辑单位,它含有一组其意义相对完整的信息;
- 大小不同:页的大小固定且由系统决定,而段的长度却不固定,由其所完成的功能决定;
- 地址空间不同: 段向用户提供二维地址空间;页向用户提供的是一维地址空间;
- 信息共享:段是信息的逻辑单位,便于存储保护和信息的共享,页的保护和共享受到限制;
- 内存碎片:页式存储管理的优点是没有外碎片(因为页的大小固定),但会产生内碎片(一个页可能填充不满);而段式管理的优点是没有内碎片(因为段大小可变,改变段大小来消除内碎片)。但段换入换出时,会产生外碎片(比如4k的段换5k的段,会产生1k的外碎片)。
9.操作系统中进程调度策略有哪几种
- FCFS(先来先服务,队列实现,非抢占的):先请求CPU的进程先分配到CPU
- SJF(最短作业优先调度算法):平均等待时间最短,但难以知道下一个CPU区间长度
- 优先级调度算法(可以是抢占的,也可以是非抢占的):优先级越高越先分配到CPU,相同优先级先到先服务,存在的主要问题是:低优先级进程无穷等待CPU,会导致无穷阻塞或饥饿;解决方案:老化
- 时间片轮转调度算法(可抢占的):队列中没有进程被分配超过一个时间片的CPU时间,除非它是唯一可运行的进程。如果进程的CPU区间超过了一个时间片,那么该进程就被抢占并放回就绪队列。
- 多级队列调度算法:将就绪队列分成多个独立的队列,每个队列都有自己的调度算法,队列之间采用固定优先级抢占调度。其中,一个进程根据自身属性被永久地分配到一个队列中。
- 多级反馈队列调度算法:与多级队列调度算法相比,其允许进程在队列之间移动:若进程使用过多CPU时间,那么它会被转移到更低的优先级队列;在较低优先级队列等待时间过长的进程会被转移到更高优先级队列,以防止饥饿发生。
10.什么是虚拟内存
1).内存的发展历程
没有内存抽象(单进程,除去操作系统所用的内存之外,全部给用户程序使用) —> 有内存抽象(多进程,进程独立的地址空间,交换技术(内存大小不可能容纳下所有并发执行的进程)
)—> 连续内存分配(固定大小分区(多道程序的程度受限),可变分区(首次适应,最佳适应,最差适应),碎片) —> 不连续内存分配(分段,分页,段页式,虚拟内存)
2).虚拟内存
虚拟内存允许执行进程不必完全在内存中。虚拟内存的基本思想是:每个进程拥有独立的地址空间,这个空间被分为大小相等的多个块,称为页(Page),每个页都是一段连续的地址。这些页被映射到物理内存,但并不是所有的页都必须在内存中才能运行程序。当程序引用到一部分在物理内存中的地址空间时,由硬件立刻进行必要的映射;当程序引用到一部分不在物理内存中的地址空间时,由操作系统负责将缺失的部分装入物理内存并重新执行失败的命令。这样,对于进程而言,逻辑上似乎有很大的内存空间,实际上其中一部分对应物理内存上的一块(称为帧,通常页和帧大小相等),还有一些没加载在内存中的对应在硬盘上,如图5所示。
注意,请求分页系统、请求分段系统和请求段页式系统都是针对虚拟内存的,通过请求实现内存与外存的信息置换。
由图5可以看出,虚拟内存实际上可以比物理内存大。当访问虚拟内存时,会访问MMU(内存管理单元)去匹配对应的物理地址(比如图5的0,1,2)。如果虚拟内存的页并不存在于物理内存中(如图5的3,4),会产生缺页中断,从磁盘中取得缺的页放入内存,如果内存已满,还会根据某种算法将磁盘中的页换出。
3). 页面置换算法
FIFO先进先出算法:在操作系统中经常被用到,比如作业调度(主要实现简单,很容易想到);
LRU(Least recently use)最近最少使用算法:根据使用时间到现在的长短来判断;
LFU(Least frequently use)最少使用次数算法:根据使用次数来判断;
OPT(Optimal replacement)最优置换算法:理论的最优,理论;就是要保证置换出去的是不再被使用的页,或者是在实际内存中最晚使用的算法。
11.守护进程、僵尸进程和孤儿进程
- 守护进程就是在后台运行,不与任何终端关联的进程,通常情况下守护进程在系统启动时就在运行,它们以root用户或者其他特殊用户(apache和postfix)运行,并能处理一些系统级的任务。
- 一个进程使用fork创建子进程,如果子进程退出,而父进程并没有调用wait或waitpid获取子进程的状态信息,那么子进程的进程描述符仍然保存在系统中。这种进程称之为僵尸进程。
- 一个父进程退出,而它的一个或多个子进程还在运行,那么那些子进程将成为孤儿进程。孤儿进程将被init进程所收养,并由init进程对它们完成状态收集工作。
12.处理僵尸进程方法
- 通过信号机制
子进程退出时向父进程发送SIGCHILD信号,父进程处理SIGCHILD信号。在信号处理函数中调用wait进行处理僵尸进程。
- 两次fork()
原理是将子进程成为孤儿进程,从而其的父进程变为init进程,通过init进程可以处理僵尸进程。
13.进程终止的几种方式
正常退出
- 从main函数返回–语言级别的返回操作
- 调用exit–C库函数
- 调用_exit–系统调用
异常退出
- 调用abort 产生SIGAORT信号
- 由信号终止 ctrl+c /SIGINT
14.linux中异常和中断的区别
相同点:
- 最后都是由CPU发送给内核,由内核去处理
- 处理程序的流程设计上是相似的
不同点:
- 产生源不相同,异常是由CPU产生的,而中断是由硬件设备产生的
- 内核需要根据是异常还是中断调用不同的处理程序
- 中断不是时钟同步的,这意味着中断可能随时到来;异常由于是CPU产生的,所以,它是时钟同步的
- 当处理中断时,处于中断上下文中;处理异常时,处于进程上下文中
11.一般情况下在Linux/windows平台下栈空间的大小
- 在Linux下是由系统环境变量来控制栈的大小的,默认8M。
- Windows下可以由编译器决定栈大小,VC++ 6.0 默认的栈空间是1M。
12.五种IO模型
同步,异步,阻塞&非阻塞的概念:
- 所谓同步,就是在发出一个功能调用时,在没有得到结果之前,该调用就不返回。也就是必须一件一件事做,等前一件做完了才能做下一件事。
- 异步的概念和同步相对。当一个异步过程调用发出后,调用者不能立刻得到结果。实际处理这个调用的部件在完成后,通过状态、通知和回调来通知调用者。
- 阻塞调用是指调用结果返回之前,当前线程会被挂起(线程进入非可执行状态,在这个状态下,cpu不会给线程分配时间片,即线程暂停运行)。函数只有在得到结果之后才会返回。
- 非阻塞和阻塞的概念相对应,指在不能立刻得到结果之前,该函数不会阻塞当前线程,而会立刻返回。
区别:
- 同步IO和异步IO的区别就在于:数据拷贝的时候进程是否阻塞
- 阻塞IO和非阻塞IO的区别就在于:应用程序的调用是否立即返回
五种IO模型:
阻塞I/O,非阻塞I/O,I/O复用,信号驱动I/O,异步I/O
13.程序从堆中动态分配内存时,虚拟内存上怎么操作的
内存分配方式
Malloc/Free主要实现的是动态内存分配,要理解它们的工作机制,就必须先了解操作系统内存分配的基本原理。
在操作系统中,内存分配主要以下面三种方式存在:
- 静态存储区域分配。内存在程序编译的时候或者在操作系统初始化的时候就已经分配好,这块内存在程序的整个运行期间都存在,而且其大小不会改变,也不会被重新分配。例如全局变量,static变量等。
- 栈上的内存分配。栈是系统数据结构,对于进程/线程是唯一的,它的分配与释放由操作系统来维护,不需要开发者来管理。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时,这些存储单元会被自动释放。栈内存分配运算内置于处理器的指令集中,效率很高,不同的操作系统对栈都有一定的限制。
- 堆上的内存分配,亦称动态内存分配。程序在运行的期间用malloc申请的内存,这部分内存由程序员自己负责管理,其生存期由开发者决定:在何时分配,分配多少,并在何时用free来释放该内存。这是唯一可以由开发者参与管理的内存。使用的好坏直接决定系统的性能和稳定。
动态内存分配概述
首先,对于支持虚拟内存的操作系统,动态内存分配都是建立在操作系统的虚拟内存分配之上的,虚拟内存分配主要包括:
- 进程使用的内存地址是虚拟的(每个进程感觉自己拥有所有的内存资源),需要经过页表的映射才能最终指向系统实际的物理地址。
- 主内存和磁盘采用页交换的方式加载进程和相关数据,而且数据何时加载到主内存,何时缓存到磁盘是OS调度的,对应用程序是透明的。
- 虚拟存储器给用户程序提供了一个基于页面的内存大小,在32位系统中,用户可以页面大小为单位,分配到最大可以到4G(内核要使用1G或2G等内存地址)字节的虚拟内存。
- 对于虚拟内存的分配,操作系统一般先分配出应用要求大小的虚拟内存,只有当应用实际使用时,才会调用相应的操作系统接口,为此应用程序分配大小以页面为单位的实际物理内存。
- 不是所有计算机系统都有虚拟内存机制,一般在有MMU硬件支持的系统中才有虚拟内存的实现。许多嵌入式操作系统中是没有虚拟内存机制的,程序的动态分配实际是直接针对物理内存进行操作的。许多典型的实时嵌入式系统如Vxworks、Uc/OS 等就是这样。
14.交换空间与虚拟内存的关系
首先,这两个概念分别对应windows和linux,即:
- windows:虚拟内存
- linux:swap分区
windows即使物理内存没有用完也会去用到虚拟内存,而Linux不一样 Linux只有当物理内存用完的时候才会去动用虚拟内存(即swap分区)
swap类似于windows的虚拟内存,不同之处在于,Windows可以设置在windows的任何盘符下面,默认是在C盘,可以和系统文件放在一个分区里。而linux则是独立占用一个分区,方便由于内存需求不够的情况下,把一部分内容放在swap分区里,待内存有空余的情况下再继续执行,也称之为交换分区,交换空间是其中的部分
windows的虚拟内存是电脑自动设置的
Linux的swap分区是装系统的时候分好的
15.可重入内核与可重入函数
可重入内核
指若干个进程可以同时在内核态下执行,也就是说多个进程可以在内核态下并发执行内核代码。在单处理器上,只能实现微观上的串行,宏观上的并行,即任意时刻,只有一个进程真正执行,其他进程处于阻塞或者等待状态。这里的可重入,是指可以多个进程进入内核,并不是重复/重新进入内核。
对于linux来说,可重入内核代码包含可重入函数和非可重入函数。
可重入函数
- 指运行时只改变局部数据结构,不改变全局数据结构;
- 不可重入函数是指运行该函数时也需要改变全局数据结构。
- 如果有多个进程进入不可重入函数时,需要相应的锁机制(互斥锁,自旋锁)来保证同一时刻只有一个进程改变涉及到的全局数据。
16.操作系统动态内存分配的几种策略
- 首次适应:首次适应策略要求空闲区按其起始地址从小到大排列,当某一用户作业要求装入内存时,存储分配程序从起始地址最小的空间区开始扫描,直到找到满足该作业要求的空闲区为止。
- 循环首次适应:在查找空闲区时,不再每次从链首开始查找,而是从上一次找到的空闲区的下一个空闲区开始查找,直到找到一个能满足要求的空闲区为止,并从中划出一块与请求大小相等的内存空间分给该作业。
- 最佳适应:该策略总是把满足要求,又使最小的空闲区分配给请求作业,即在空闲区表中,按空闲区的大小从小到大排列,建立索引,当用户作业请求内存空间时,从索引表中找到第一个满足该作业的空闲区分给它。
- 最差适应:该策略总是把最大的空闲区分配给请求作业,空闲区表(空闲区链)中的空闲分区要按大小从大到小进行排序,自表头开始查找到第一个满足要求的空闲分区分配给作业。
17.内部碎片和外部碎片
内存碎片分为:内部碎片和外部碎片
内部碎片
- 内部碎片就是已经被分配出去(能明确指出属于哪个进程)却不能被利用的内存空间;
- 内部碎片是处于(操作系统分配的用于装载某一进程的内存)区域内部或页面内部的存储块。占有这些区域或页面的进程并不使用这个存储块。而在进程占有这块存储块时,系统无法利用它。直到进程释放它,或进程结束时,系统才有可能利用这个存储块。
- 单道连续分配只有内部碎片。多道固定连续分配既有内部碎片,又有外部碎片。
外部碎片
- 外部碎片指的是还没有被分配出去(不属于任何进程),但由于太小了无法分配给申请内存空间的新进程的内存空闲区域。
-
外部碎片是处于任何两个已分配区域或页面之间的空闲存储块。这些存储块的总和可以满足当前申请的长度要求,但是由于它们的地址不连续或其他原因,使得系统无法满足当前申请。
18.系统调用进入内核态的过程
什么是系统调用
是操作系统为用户提供的一系列API;系统调用将用户的请求发给内核,内核执行完以后,将结果返回给用户;
系统调用的流程
19.内核态和用户态的区别
- 内核态与用户态是操作系统的两种运行级别,当程序运行在3级特权级上时,就可以称之为运行在用户态。因为这是最低特权级,是普通的用户进程运行的特权级,大部分用户直接面对的程序都是运行在用户态;
-
当程序运行在0级特权级上时,就可以称之为运行在内核态。
-
运行在用户态下的程序不能直接访问操作系统内核数据结构和程序。当我们在系统中执行一个程序时,大部分时间是运行在用户态下的,在其需要操作系统帮助完成某些它没有权力和能力完成的工作时就会切换到内核态(比如操作硬件)。
-
这两种状态的主要差别是
- 处于用户态执行时,进程所能访问的内存空间和对象受到限制,其所处于占有的处理器是可被抢占的
- 处于内核态执行时,则能访问所有的内存空间和对象,且所占有的处理器是不允许被抢占的。
20.常见的进程调度算法以及linux的进程调度
进程调度:在操作系统中调度是指一种资源分配。调度算法:根据系统的资源分配策略所规定的资源分配算法。
进程调度算法:
先来先服务(FCFS)、短作业优先(SPN)、最短剩余时间(SRT)、时间片轮转、最高响应比优先、公平共享调度
Linux系统中的进程调度方案
Linux在进行进程调度的时候把进程分为两种:1.普通进程;2.实时进程
实时进程的优先级永远比普通进程的优先级高,也就是说实时进程只要来了就可以抢占普通进程,而且还抓住处理器就不撒手,直到所有的实时进程都执行完毕,才会把处理器让出来给普通进程使用
21.中断、陷阱、故障和终止
异常的类别
- 中断:中断是异步发生的,来自处理器外部IO设备的信号(区别于同步异常:执行一条指令的结果),它不是由任何一条专门的指令造成的。例如网络适配器、磁盘控制器通过向处理器芯片上的一个管脚发信号,并将异常号放在系统总线上,来触发中断,这个异常号标识了引起中断的设备。中断处理程序总是返回到当前指令的下一条指令。
- 陷阱:陷阱是同步异常,是执行一条指令的结果。陷阱最重要的用途是在用户程序和内核之间提供系统调用接口。陷阱总返回到当前指令的下一条指令。
- 故障:故障由错误引起,它可能被故常处理程序修正,如果修正成功,将返回到当前正在执行的指令,重新执行。否则处理程序返回到内核的abort历程,将终止故障程序。故障的一个典型是缺页异常。
- 终止:由不可恢复的知名错误造成的结果,处理程序将返回到内核中的abort例程,终止应用程序。
22.Linux中常用到的命令
- 显示文件目录命令ls 如ls
- 改变当前目录命令cd 如cd /home
- 建立子目录mkdir 如mkdir xiong
- 删除子目录命令rmdir 如rmdir /mnt/cdrom
- 删除文件命令rm 如rm /ucdos.bat
- 文件复制命令cp 如cp /ucdos /fox
- 获取帮助信息命令man 如man ls
- 显示文件的内容less 如less mwm.lx
- 重定向与管道type 如type readme>>direct,将文件readme的内容追加到文direct中
23.线程互斥和同步的方法
- 互斥:互斥量、读写锁、自旋锁
- 同步:轮询结合互斥量、条件变量、信号量、屏障
24.死锁
1). 死锁的概念
在两个或者多个并发进程中,如果每个进程持有某种资源而又等待其它进程释放它或它们现在保持着的资源,在未改变这种状态之前都不能向前推进,称这一组进程产生了死锁。通俗的讲,就是两个或多个进程无限期的阻塞、相互等待的一种状态。
2). 死锁产生的四个必要条件
互斥:至少有一个资源必须属于非共享模式,即一次只能被一个进程使用;若其他申请使用该资源,那么申请进程必须等到该资源被释放为止;
占有并等待:一个进程必须占有至少一个资源,并等待另一个资源,而该资源为其他进程所占有;
非抢占:进程不能被抢占,即资源只能被进程在完成任务后自愿释放
循环等待:若干进程之间形成一种头尾相接的环形等待资源关系
3). 死锁的处理基本策略和常用方法
解决死锁的基本方法主要有:预防死锁、避免死锁、检测死锁、解除死锁 、鸵鸟策略 等。
(1). 死锁预防
死锁预防的基本思想是 只要确保死锁发生的四个必要条件中至少有一个不成立,就能预防死锁的发生,具体方法包括:
打破互斥条件:允许进程同时访问某些资源。但是,有些资源是不能被多个进程所共享的,这是由资源本身属性所决定的,因此,这种办法通常并无实用价值。
- 打破占有并等待条件:可以实行资源预先分配策略(进程在运行前一次性向系统申请它所需要的全部资源,若所需全部资源得不到满足,则不分配任何资源,此进程暂不运行;只有当系统能满足当前进程所需的全部资源时,才一次性将所申请资源全部分配给该线程)或者只允许进程在没有占用资源时才可以申请资源(一个进程可申请一些资源并使用它们,但是在当前进程申请更多资源之前,它必须全部释放当前所占有的资源)。但是这种策略也存在一些缺点:在很多情况下,无法预知一个进程执行前所需的全部资源,因为进程是动态执行的,不可预知的;同时,会降低资源利用率,导致降低了进程的并发性。
- 打破非抢占条件:允许进程强行从占有者哪里夺取某些资源。也就是说,但一个进程占有了一部分资源,在其申请新的资源且得不到满足时,它必须释放所有占有的资源以便让其它线程使用。这种预防死锁的方式实现起来困难,会降低系统性能。
- 打破循环等待条件:实行资源有序分配策略。对所有资源排序编号,所有进程对资源的请求必须严格按资源序号递增的顺序提出,即只有占用了小号资源才能申请大号资源,这样就不回产生环路,预防死锁的发生。
(2). 死锁避免的基本思想
死锁避免的基本思想是动态地检测资源分配状态,以确保循环等待条件不成立,从而确保系统处于安全状态。所谓安全状态是指:如果系统能按某个顺序为每个进程分配资源(不超过其最大值),那么系统状态是安全的,换句话说就是,如果存在一个安全序列,那么系统处于安全状态。资源分配图算法和银行家算法是两种经典的死锁避免的算法,其可以确保系统始终处于安全状态。其中,资源分配图算法应用场景为每种资源类型只有一个实例(申请边,分配边,需求边,不形成环才允许分配),而银行家算法应用于每种资源类型可以有多个实例的场景。
(3). 死锁解除
死锁解除的常用两种方法为进程终止和资源抢占。所谓进程终止是指简单地终止一个或多个进程以打破循环等待,包括两种方式:终止所有死锁进程和一次只终止一个进程直到取消死锁循环为止;所谓资源抢占是指从一个或多个死锁进程那里抢占一个或多个资源,此时必须考虑三个问题:
(I). 选择一个牺牲品
(II). 回滚:回滚到安全状态
(III). 饥饿(在代价因素中加上回滚次数,回滚的越多则越不可能继续被作为牺牲品,避免一个进程总是被回滚