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

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

死锁是指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去

死锁是两个或更多线程阻塞着等待其它处于死锁状态的线程所持有的锁。死锁通常发生在多个线程同时但以不同的顺序请求同一组锁的时候。

例如,如果线程1锁住了A,然后尝试对B进行加锁,同时线程2已经锁住了B,接着尝试对A进行加锁,这时死锁就发生了。线程1永远得不到B,线程2也永远得不到A,并且它们永远也不会知道发生了这样的事情。为了得到彼此的对象(A和B),它们将永远阻塞下去。这种情况就是一个死锁。

那么为什么会产生死锁呢?

  1、系统资源不足

  2、进程(线程)推进的顺序不恰当;

  3、资源分配不当

产生死锁的四个必要条件:

  一.互斥条件:所谓互斥就是进程在某一时间内独占资源。
  二.请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。
  三.不剥夺条件:进程已获得资源,在末使用完之前,不能强行剥夺。
  四.循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。

常见死锁形成的场景:

  1、忘记释放锁

  2、单线程重复申请锁

  3、多线程多锁申请

  4、 环形锁申请

下面说说那个检测方法,其实方法挺简单的。

有两个容器,一个用于保存线程正在请求的锁,一个用于保存线程已经持有的锁。每次加锁之前都会做如下检测:

1)检测当前正在请求的锁是否已经被其它线程持有,如果有,则把那些线程找出来

2)遍历第一步中返回的线程,检查自己持有的锁是否正被其中任何一个线程请求

 如果第二步返回真,表示出现了死锁

 

死锁的预防:

打破产生死锁的四个必要条件中的一个或几个,保证系统不会进入死锁状态。

一.打破互斥条件。即允许进程同时访问某些资源。但是,有的资源是不允许被同时访问的,像打印机等等,这是由资源本身的属性所决定的。所以,这种办法并无实用价值。
二.打破不可抢占条件。即允许进程强行从占有者那里夺取某些资源。就是说,当一个进程已占有了某些资源,它又申请新的资源,但不能立即被满足时,它必须释放所占有的全部资源,以后再重新申请。它所释放的资源可以分配给其它进程。这就相当于该进程占有的资源被隐蔽地强占了。这种预防死锁的方法实现起来困难,会降低系统性能。
三.打破占有且申请条件。可以实行资源预先分配策略。即进程在运行前一次性地向系统申请它所需要的全部资源。如果某个进程所需的全部资源得不到满足,则不分配任何资源,此进程暂不运行。只有当系统能够满足当前进程的全部资源需求时,才一次性地将所申请的资源全部分配给该进程。由于运行的进程已占有了它所需的全部资源,所以不会发生占有资源又申请资源的现象,因此不会发生死锁。
四.打破循环等待条件,实行资源有序分配策略。采用这种策略,即把资源事先分类编号,按号分配,使进程在申请,占用资源时不会形成环路。所有进程对资源的请求必须严格按资源序号递增的顺序提出。进程占用了小号资源,才能申请大号资源,就不会产生环路,从而预防了死锁。

 

 

 

转载于:https://www.cnblogs.com/wangleBlogs/p/7367561.html

你可能感兴趣的文章
codeforces 315 308
查看>>
BZOJ3998 [TJOI2015]弦论 【后缀自动机】
查看>>
CF E2 - Array and Segments (Hard version) (线段树)
查看>>
svn 架设
查看>>
k8s部署rocketmq 双主
查看>>
Linux SPI总线和设备驱动架构之四:SPI数据传输的队列化
查看>>
SIGPIPE并产生一个信号处理
查看>>
CentOS
查看>>
Explicit keyword
查看>>
Linux pipe函数
查看>>
java equals 小记
查看>>
Erdaicms旅游网站程序,微信扫码登录演示和示例程序
查看>>
15第十五章UDF用户自定义函数(转载)
查看>>
爬虫-通用代码框架
查看>>
2019春 软件工程实践 助教总结
查看>>
Remove '@Override' annotation错误
查看>>
mybatis笔记<一> Demo
查看>>
YUV 格式的视频呈现
查看>>
开通了blog写一些技术blog及感悟
查看>>
Android弹出框的学习
查看>>