文章目录
- 死锁问题
- 死锁原因
- 产生死锁的几个常见场景
- 死锁产生的四个必要条件==仅供参考
-
pthread_mutex_lock(),线程互斥量死锁,与sleep没有关联.
项目上,定位死锁原因,无意中看到pthread_mutex_lock()以及 sleep()字样的文章.说的模糊不清,但是又貌似有些因果.
反复查阅资料以及测试,完全可以确认:
pthread_mutex_lock(),线程互斥量死锁,与sleep没有关联.
死锁问题
死锁原因
如果一个线程试图对同一个互斥量加锁两次(并且没有其他线程释放锁),自身就会陷入死锁状态。当该线程第一次去向互斥量加锁时,由于该互斥量上并没有锁,所以可以加锁成功,但是该线程第二次去向互斥量加锁,由于该互斥量上已经加过锁了,所以会把自身挂起阻塞,直到该锁被释放,但是自己又被挂起了,所以不会有人去释放的,这就造成了死锁问题。
一般情况下,如果同一个线程先后两次调用lock,在第二次调用时,由于锁已经被占用,该线程会挂起等待占用锁的线程释放锁,然而锁正是被自己占用着的,该线程又被挂起而没有机会释放锁,因此 就永远处于挂起等待状态了,于是就形成了死锁(Deadlock)。
当一个线程去申请一个已经被持有,但是还没有释放的互斥量时,线程将会被阻塞,直到该互斥量被释放。如果该互斥量不被释放,该线程将会被一直阻塞。死锁就是,一个线程阻塞的等待一个永远不会为真的条件。
产生死锁的几个常见场景
假设程序中现在有一个互斥量,然后一个线程对该互斥量已经加锁,但是在加锁和解锁的这段代码中,如果该区域代码又试图向该互斥量申请锁,那么就会造成自身挂起等待,从而导致死锁。
假设程序中使用两个互斥量,线程A首先锁住一个互斥量,然后线程B也锁住另外一个互斥量,拥有第一个互斥量的线程A又去试图锁住第二个互斥量,而拥有第二个互斥量的线程B试图申请锁住第一个互斥量,这就会导致两个线程此时都在挂起堵塞中,两个线程都在相互请求另一个线程的资源导致两个线程都无法向前运行,于是产生了死锁问题。
死锁产生的四个必要条件==仅供参考
上边的两种产生死锁的场景是在互斥量的条件下,但是这造成死锁的场景,并不局限于互斥量,只要满足产生死锁的条件,就会出现死锁。针对死锁的概念,大牛们总结出来了四条产生死锁的必要条件:
四个条件必须同时满足,才会可能造成死锁。只要有一个条件不满足,就不会造成死锁。死锁的产生并不仅会只有使用互斥量时会发生,只要满足四个条件也可能产生死锁。在系统中,有许多只能被互斥性访问的独占资源,如请求独占性的io设备,打印机等,在对其进行操作时,也有可能造成死锁。
互斥条件
互斥条件与锁一样,要么能被申请,要么就只能等待。在任意时刻,某份资源只能被一个进程或线程使用。
占有和等待条件
占有和等待条件是指某个线程或进程,在占有某份资源后还可以申请其他的资源。
不可抢占条件
当某份资源被某一进程或线程占有时,不能被其他线程或进程强制性的抢占,只能被占有它的线程主动的释放。
环路等待条件
死锁发生时,系统中一定有两个或两个以上的进程组成的一条环路,该环路中的每一个线程或进程都在等待下一个进程所占用的资源。
参考:
<UNIX环境高级编程>,11.6,线程同步章节.
Linux多线程学习(2)–线程的同步与互斥及死锁问题(互斥量和条件变量)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)