linux线程安全篇之----死锁问题

目录

1.死锁问题

1.1、死锁的两种场景

第一种场景

第二种场景

2.造成死锁的必要条件

2.1、不可剥夺

2.2、循环等待

2.3、互斥条件

2.4、请求与保持

3.预防死锁

3.1.破坏必要条件:循环等得请求与保持

3.2、避免锁没有被释放

3.3、资源一次性分配


 

 

 

1.死锁问题

1.1、死锁的两种场景

  • 第一种场景

    • 线程加锁之后并没有将锁释放
    • 1.这里我们模拟两个线程导致死锁的情况:将锁锁上之后线程退出,导致其他线程拿不到这把锁造成死锁情况

      ba96c57e753ae1c871910f8d99a99d33.png

    • 我们让程序跑起来发现一直不退出

      7bca3c7d96e9250a5e9e0592e59b8b84.png

    • 然后查看调用堆栈我们发现一个创建出来两个线程现在只剩下一个,而且他在死等锁,

      098d3d33d31c82bf2604681bb0cc2062.png

    • 2.接下来我们来模拟一个线程将锁锁上没有释放,导致死锁的情况:watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5pyI5Y2K5pyo5pak,size_20,color_FFFFFF,t_70,g_se,x_16
    • 我们运行程序发现程序卡死

      d66cc43300afc5c14d0dc28ae1570566.png

    • 我们查看调用栈发现是和上面一样的情况watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5pyI5Y2K5pyo5pak,size_20,color_FFFFFF,t_70,g_se,x_16
  • 第二种场景

    • 两个线程都持有对方想要的锁,然后造成死锁watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5pyI5Y2K5pyo5pak,size_20,color_FFFFFF,t_70,g_se,x_16
    • 代码模拟:我们来模拟两个进程互相持有对方想要的锁的情况watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5pyI5Y2K5pyo5pak,size_20,color_FFFFFF,t_70,g_se,x_16
    • 运行结果发现直接卡死

      ba54fea0a9429b9edb1ea43345893ee3.png

    • 我们查看调用栈发现两个进程都在等待锁造成死锁

      ad42109ef683617b526b5cb6a1be28d1.png

    • 这时无论两个线程的最后一行下面写什么代码都是无法执行的

      dbcb95d3bdda94790f560896dc3a52ec.png

    • 死锁gdb调试watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5pyI5Y2K5pyo5pak,size_20,color_FFFFFF,t_70,g_se,x_16
    • t+线程序号=跳转到某个线程当中

      42c86a5afa2a0556fb4a41934e464095.png

    • 【p g_lock】中owner可以看到锁的持有者watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5pyI5Y2K5pyo5pak,size_20,color_FFFFFF,t_70,g_se,x_16

2.造成死锁的必要条件

  • 2.1、不可剥夺

    • 不可剥夺:线程获取到互斥锁之后, 除了自己释放,其他线程是不能进行释放的。
  • 2.2、循环等待

    • 循环等待:线程A拿着1锁, 请求2锁, 同时线程B拿着2锁, 请求1锁。

      4e39e6338bd64195877ae0bda46af716.png

  • 2.3、互斥条件

    • 互斥条件: 一个互斥锁,在同一时间只 能被一个线程所拥有。
  • 2.4、请求与保持

    • 请求与保持:吃着碗里的, 看着锅里的。(已经拿到一个锁,还想请求另外一个锁,和上面的循环等待场景相似)

3.预防死锁

  • 3.1、破坏必要条件:循环等得请求与保持

    9c220b72765604d66e0d360ad36423bf.png

  • 运行结果:程序没有卡死正常退出。

    387c7110795fcb962587f3856fd5df48.png

  • 加锁顺序一致,都先加1锁, 再加2锁

    c5d132d4a83713a88d43f512432a8d02.png

  • 运行结果:程序没有卡死正常退出。

    11c4628e6ac6419a303cb1adb9cd7342.png

  • 3.2、避免锁没有被释放

    • 在所有可能线程退出的地方都进行解锁
  • 3.3、资源一次性分配

  • 多个资源在代码当中又可能每一个资源都需要使用不同的锁进行保护
  • 例如:
  • 全局变量A,需要1锁
  • 全局变量B,需 要2锁
  • 88d91da6c471e6dbd4a7b2bf5c3dbd58.png

    就有可能多个线程在使用这两个资源的时候,出现循环等待的情况。
  • 这里的解决方式我们只需要给将A和B用同一把锁保护即可(资源一次性分配)。

看到这里如果觉得有用不如点个赞再走吧!!!9bfaa99bea294470b647ef3f99c16754.jpeg

 

 

  • 7
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

月半木斤

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值