死锁指的是一个线程通过加锁占用了一份共享资源,但是这个线程自己又因为某种情况陷入死循环或者永久等待的状态。这里只说明死锁是什么,并不解释如何避免死锁
1、死锁案例
最简单的死锁就是一个线程重复申请锁,我们沿用之前的抢票模型(5个线程同时抢,为了避免线程共享资源冲突,引入了互斥锁)
(12条消息) Linux环境下 解决线程共享资源冲突 —— 互斥锁(代码实现及底层原理)_abs(ln(1+NaN))的博客-CSDN博客https://blog.csdn.net/challenglistic/article/details/124755816?spm=1001.2014.3001.5501我们在申请锁的地方再加一句申请锁的语句,也就是说我们申请了两次互斥锁
那么最后的结果是进程陷入了永久等待的状态
2、原因分析
为什么会出现这样的情况呢?在互斥锁的底层原理,我们了解到,一个线程一旦申请锁,而且申请成功了,那么这个线程就会一直保存着这个 1 ,一直到解锁才会把 1 还给内存里的mutex;如果申请失败,就会被挂起
回到上面的内容,线程A第一次执行 pthread_mutex_lock(mtx) 就是在向内存的mutex 申请锁,然后mutex很乐意的把锁给了线程A,然后线程A就可以访问临界区了
第二次这个线程A又来找mutex申请锁了,但是此时mutex的值为 0 ,因为锁已经给了线程A,此时会申请失败,此时线程A就会被挂起!
现在线程A被挂起了,被唤醒的条件是 有人把锁还给内存,但是这把锁就在自己手里,但是自己却在等别人把锁还给内存。明明自己骑着驴,却做着找驴的事,这就导致了线程的永久等待。