博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
线程死锁
阅读量:2442 次
发布时间:2019-05-10

本文共 2262 字,大约阅读时间需要 7 分钟。

转载自:

一、死锁

由于两个或者两个以上的(进程)去抢夺一份资源而造成阻塞的状态叫做死锁, 

如果出现了死锁,会造成线程的循环等待,如果没有外力的帮助,就会一直维持着某种状态

二、死锁的产

死锁的产生有如下四个必要条件 

      1. 资源是互斥的,同一时刻只能有一个进程占有该资源 
      2. 资源的释放只能有该进程自己完成 
      3. 线程在获取到需要资源之前,不会释放已有资源 
      4. 存在这么一条循环等待的队列,线程T1,T2,T3…, Tn 
      T1持有自己的资源请求T2的资源,….Tn持有自己的资源请求T1的资源 

 多线程如果设计的不合理的话,很可能就会出现死锁.当两个或者多个线程同时想要去获取共享资源的锁时,但每个线程都要等其他线程把他们各自的锁给释放,才能继续运行,这就是死锁.出现死锁必须具备以下几点 

* 要有两个或两个以上的线程 
* 至少有两个共享资源的锁 
* 至少存在两个线程各自拥有一个锁 
* 现在这两个线程在等待获取彼此的锁,这就出现死锁了
 

三、处理死锁的方式

死锁的预防

其实死锁的4个发生条件都是必要条件,也就是说4个条件缺一不可,我们可以通过破坏其中任意一个条件来预防死锁。 

 1.破坏资源的互斥性

这是不可能滴,在访问临界资源时,至少要保证对资源的访问是互斥的,例如一台打印机在任意一时刻只能打印一个文件

2.破坏不可抢占的条件

允许其他资源对资源的抢夺 

方案 1.在该方案下,如果占有某些资源的进程在进一步申请资源被拒绝后,就必须释放原本占有的资源,如果有必要,则可以再次申请这些资源或者另外资源

方案 2. 如果一个进程请求当前被另一个进程占有的资源,则操作系统可以抢占另一个进程,要求它释放资源.当然这必须是在两个不同优先级的进程才能生效

3.破坏请求和保持条件

在系统中不允许进程在已获得某种资源的情况下,申请其他资源.即阻止进程在持有资源的同时申请资源

方案 1. 所有进程在运行之前,必须一次性地申请在整个运行过程中所需的全部资源,在运行期间不能申请资源,带来的问题是

a.假设一个进程需要多种类型的资源,其中只有一组不满足进程所需,其他资源也必须保持空闲状态,严重影响资源的利用率 

b.会使某些进程长期得不到资源而发生饥饿问题,例如解决哲学家就餐问题时,我那篇文章就采用的是此方案,每个哲学家同时申请两个筷子,否则就等待,有可能某些哲学家长期不能一次申请到两个筷子而饿死….

方案2 要求每个进程在申请资源时,同时放弃已占有的资源,即使可能该进程很快又需要此资源 

当然这中方案也不是完全可以避免死锁 假设两个哲学家两个筷子,每个哲学家都拿着一个筷子,在申请对方筷子时又释放掉自己的筷子,就会又陷入死锁

4.破坏循环等待条件

将系统中的所有资源统一编号,进程可在任何时刻提出申请资源,但申请必须按资源的顺序提出,例如 1只能申请2号的资源,2号不能申请1号的资源。

四、经典的银行家算法

有5个向量 

Max:表示线程对每类资源的最大需求量;

Allocation:表示系统给线程已分配每类资源的数目;

Need:表示线程还需各类资源数目;

Available:表示系统当前剩下的资源。

当一个线程发出request时,先看request[i]是否小于其需求need 如果小于则 

进入查看request是否小于当前系统剩余总量Available ,如果满足则 暂时修改当前工作状态

Max-=request

Allocation+=request

Need-=request

Available-=request

然后进行安全检测 : 

设置一个工作向量 work = 此刻的Available 
查看剩余的进程是否有仍未完成的资源 
finish = flase

而且其所需资源(Need) < work(当前肾剩余资源)

若找到就将资源费配给他

等它运行完毕后就会释放资源,此时 

work = 之前剩余的work + 此进程运行时的资源MAX

之后当所有 

finish = flase 的资源都可以获得所需资源而运行完 
则表示此次分配是安全的,就可以分配

若不能满足上述条件,则表明此次分配是不安全的 就撤回其申请.

五、安全算法的原因

本质: 当我给你这个进程分配资源以后

要保证我剩余的资源能够在 剩下的进程中周转开来

例如 给 1分配资源后 ,剩下3个进程都开始申请资源

假设剩下三个进程ID 为 A, B ,C

假设ABC三个人的状态都是flase 

给进程1分配资源后,剩余资源为 available 
一直轮询 ABC 剩下的资源你们谁能完全利用,完成你们的事情, 然后后把你们占有的所有资源都归回来

假设A 发现剩下的资源他可以利用, (need < available ) 

那么它干完事情后就把它资源全部归还

此时剩下的资源就是 available + alloctoin(A)

再去轮询 看剩下 B和C是否能够完成 他们的事情

当ABC都能完成他们的事情,那么给1分配他所需的资源才是合理的 (此时成为安全序列) 

因为总(存在一种分配方案使 ABC都可以完成任务的分配 ) 
若不满足以上的检查,分配出去以后就是不安全序列 ,有可能就会发生死锁

eg:

假如第一个进程获得 所需资源 后,释放的资源和剩余的资源加起来不能满足以后所有进程中任何一个的需求量 剩下所有进程都会去占有资源而无法运行完,就不会去释放资源, 

就会造成进程的死锁问题

你可能感兴趣的文章
ecmascript v3_节点v12中的新ECMAScript模块简介
查看>>
vue jest 测试_Vue.js中的Jest快照测试简介
查看>>
Electron.js简介-第2部分:Todo应用
查看>>
gatsby_Gatsby CLI快速参考
查看>>
vue中的突变方法在哪_了解GraphQL中的突变
查看>>
redis修改配置重启命令_如何从命令行更改Redis的配置
查看>>
盖茨比乔布斯_使用wrapRootElement挂钩在盖茨比进行状态管理
查看>>
盖茨比乔布斯_通过盖茨比使用Airtable
查看>>
mern技术栈好处?_如何开始使用MERN堆栈
查看>>
路由器接路由器_路由器之战:到达路由器vsReact路由器
查看>>
rxjs 搜索_如何使用RxJS构建搜索栏
查看>>
如何在Debian 10上安装MariaDB
查看>>
go函数的可变长参数_如何在Go中使用可变参数函数
查看>>
react开源_React Icons让您可以访问数百个开源图标
查看>>
debian 服务器_使用Debian 10进行初始服务器设置
查看>>
joi 参数验证_使用Joi进行节点API架构验证
查看>>
react-notifications-component,一个强大的React Notifications库
查看>>
如何在Debian 10上设置SSH密钥
查看>>
如何在Debian 10上安装Node.js
查看>>
了解css_了解CSS的特异性
查看>>