互斥锁的错误使用 —— 死锁

死锁指的是一个线程通过加锁占用了一份共享资源,但是这个线程自己又因为某种情况陷入死循环或者永久等待的状态。这里只说明死锁是什么,并不解释如何避免死锁

1、死锁案例

最简单的死锁就是一个线程重复申请锁,我们沿用之前的抢票模型(5个线程同时抢,为了避免线程共享资源冲突,引入了互斥锁)

(12条消息) Linux环境下 解决线程共享资源冲突 —— 互斥锁(代码实现及底层原理)_abs(ln(1+NaN))的博客-CSDN博客https://blog.csdn.net/challenglistic/article/details/124755816?spm=1001.2014.3001.5501我们在申请锁的地方再加一句申请锁的语句,也就是说我们申请了两次互斥锁

互斥锁的错误使用 —— 死锁_第1张图片

 那么最后的结果是进程陷入了永久等待的状态

2、原因分析

为什么会出现这样的情况呢?在互斥锁的底层原理,我们了解到,一个线程一旦申请锁,而且申请成功了,那么这个线程就会一直保存着这个 1 ,一直到解锁才会把 1 还给内存里的mutex;如果申请失败,就会被挂起

互斥锁的错误使用 —— 死锁_第2张图片

回到上面的内容,线程A第一次执行 pthread_mutex_lock(mtx) 就是在向内存的mutex 申请锁,然后mutex很乐意的把锁给了线程A,然后线程A就可以访问临界区了

互斥锁的错误使用 —— 死锁_第3张图片

第二次这个线程A又来找mutex申请锁了,但是此时mutex的值为 0 ,因为锁已经给了线程A,此时会申请失败,此时线程A就会被挂起!

现在线程A被挂起了,被唤醒的条件是 有人把锁还给内存,但是这把锁就在自己手里,但是自己却在等别人把锁还给内存。明明自己骑着驴,却做着找驴的事,这就导致了线程的永久等待。

你可能感兴趣的:(Linux,基础,linux,c++)