死锁问题,4个必要条件+避免死锁
2023-12-13 06:38:48
目录
引入
我们用加锁的方式保证了多个线程访问临界资源时,不会出现数据紊乱的问题
但是,锁的引入,会导致出现其他的问题
死锁
概念
- 在多线程或多进程的并发环境中,两个或多个进程或线程被永久阻塞,因为它们在等待对方释放资源,而自己却不释放已经占有的资源
- 进程或线程无法继续执行,而无法自行解除阻塞
示例
多把锁
一个线程可以申请多把锁:
- 线程A申请了a锁,线程B申请了b锁
- 但在两个线程释放锁之前,线程A又需要b锁(也就是需要访问b锁范围内的临界区代码),那么A就会等待b锁的释放
- 但是此时,如果线程B需要用a锁,就会形成死锁了
- 因为a锁还正在被线程A持有,线程B需要等待a锁的释放
- 于是,这两个线程就互相等待对方释放锁,但都处于挂起状态,而锁是无法自己释放的,所以他俩只能一直这么等下去
单锁
如果只需要一把锁,也可能会出现死锁问题(当然,这是特殊情况)
- 如果一个线程已经申请了a锁,在释放锁之前,它又不小心申请了锁 / 把释放锁的函数名unlock写成了lock,就会形成死锁
- 因为锁已经被持有(虽然这个人是自己),但是lock函数的第一句就是将al赋为0,所以自己持有的状态并不影响lock的执行
- 他依然会用内存中mutex的0和al的0交换,然后判断失败被挂起
- 挂起后,线程带走自己的上下文数据,也就是al中的0
- 这样,锁就丢失了,线程永远也无法等待到锁
4个必要条件?
互斥条件
- 一个资源每次只能被一个执行流使用
- (这是基础条件,我们只有使用了互斥锁,才会出现死锁问题)
请求与保持条件
- 一个执行流因请求资源而阻塞时,对已获得的资源保持不放
- (也就是既要又要,他不会放弃自己的,又会向别人索要)
不剥夺条件
- 一个执行流已获得的资源,在末使用完之前,不能强行剥夺
- (他虽然向别人索要,但只是一种请求,不会也不能强制拿取)
循环等待条件
- ???????若干执行流之间形成一种头尾相接的循环等待资源的关系
- 也就是说,申请资源的方向要形成环
用途?
因为是必要条件,所以只要这四个条件之一不满足,即可避免死锁问题
比如:
- 我们只有在必要时才使用锁,并且要将锁的范围尽可能的缩小
- 在申请别人的资源不成功若干次后,可以考虑先释放掉自己的锁(万一对方就是在等这个锁呢)
- 尽量在一个锁范围内完成对共享资源的处理,避免出现多个锁 / 严格控制每个线程申请锁的顺序
文章来源:https://blog.csdn.net/m0_74206992/article/details/134759621
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!