linux:死锁

在实现线程互斥中,我们是使用了互斥锁,那如果不合理的使用互斥锁,会带来什么危害呢?比如加锁之后却忘记解锁,会导致以下结果:

1.内存泄露
2.死锁

线程互斥请看上一篇博客:https://blog.csdn.net/dangzhangjing97/article/details/79947187

1.死锁是什么

比如你在锁门时,把门锁了,然后出去了,把钥匙丢了,回来之后,那门就开不开了,门就一直会处于死锁状态
在线程中,死锁是指给一个临界区加了锁之后,忘记解锁,那线程就会一直处在临界区出不来,因为没有解锁

死锁现象
跟死循环的现象一样,程序会一直处于运行状态

2.死锁场景

1.一个线程已经获取到锁,现在又去获取锁,就会出现死锁(调用lock的时候,如
果当前的mutex变量已经被加锁,lock函数就会阻塞等待,一直等到unlock)

2.现在有两个线程,分别为消线程A和线程B,线程A获取了1号锁,线程B获取了2
号锁,现在A尝试获取2号锁,线程B尝试获取3号锁,这个时候双方都无法拿到对
方的锁,并且会在获取锁的函数(lock)中阻塞等待
      程序跑起来之后,因为两个线程互相去获取对方已经持有的锁,导致环路等
  待,出现死锁

如果线程和锁的数目更多了,就会使死锁问题更容易出现

3.死锁的4个必要条件

1.互斥条件
一个锁每次只能被一个线程或者进程使用;
2.请求和保持条件
一个进程或者线程因为请求某个锁而阻塞时,不会释放自己已经拿到的锁;
3.不剥夺条件
进程或者线程已经拿到的锁,自己未使用完毕之前,其他线程或者进程不能强行剥夺;
4.环路等待条件
若干进程或者线程之间形成一种头尾相接的循环等待锁的关系;

4.如何避免死锁

使临界区的代码注意以下几个方面,可有效的避免死锁的发生:

1.尽量使临界区的代码短
2.代码逻辑清晰,尽量在临界区中的代码不要存在函数调用等复杂的函数关系或者复杂的变量关系,也尽量不要申请其他的互斥资源,应使代码简单,一眼就可以看懂其表达的意思;
3.应使临界区的代码的执行速度尽量快,如果代码的执行速度很快的话,就算出现死锁,程序也可能表现不出来;

猜你喜欢

转载自blog.csdn.net/dangzhangjing97/article/details/79951735