【Linux】线程安全:死锁(附加gdb调试分析)

线程知识合集:
【Linux】线程概念 && 线程控制(接口详谈)&& 僵尸线程的产生和解决
【Linux】线程安全:互斥 & 同步



死锁的产生场景

情况1:线程加锁后,并没有释放互斥锁

模拟代码:
在这里插入图片描述

结果分析:
在这里插入图片描述


情况2:两种(或多个)线程分别拿着一个锁,同时也请求其他的锁

模拟代码:
在这里插入图片描述

结果分析:
在这里插入图片描述


死锁的gdb调试分析

上述情况分析,并不是很明确,通过gdb调试,观察发生死锁前,每个g_lock被哪个线程所持有,即可更加清晰的分析。

gdb调试指令

首先需下载gdb工具(通过包管理器进行安装)

yum -y install gdb

查看GDB版本:gdb -v
在这里插入图片描述

gdb调试的必须是debug文件,但编译器默认生成release文件,若想调试,必须在编译命令后添加-g,告诉编译器在编译程序时加入调试信息:

gcc -g $^ -o $@

常用指令:

  • 启动gdb:gdb test.exe
  • 打断点: (gdb)break (b)
// 启动gdb
gdb test.exe
-----------------------------------------------
// 查看源码和行号:(gdb)list (l)
l + 开始行数,默认显示十行
-----------------------------------------------
// 打断点:(gdb)break (b)
	// 根据行号设置断点
	(gdb) b 5 
	// 根据函数设置断点
	(gdb) b main
	// 根据条件设置断点
	(gdb) b test.c:10 if a == 1
	// 设置临时断点(只生效一次)
	(gdb) tbreak test.c:12

// 显示所有断点
(gdb) info breakpoints

// 清除断点
	// 清除某个断点 
	(gdb) delete 4
	// 清除所有断点 
	(gdb) delete 
	// 清除当前行断点  
	(gdb) clear
-----------------------------------------------
// 运行和继续
	// 运行(按断点)
	(gdb) run (r)
	// 继续执行到下一个断点
	(gdb) continue (c)
	// 逐语句调试
	(gdb) next (n)
	// 逐步调试(进入函数体)
	(gdb) step(s)
	// 跳出函数体(执行到指定行)
	(gdb) until (u)
	// 跳转指定位置
	(gdb) jump(j)	
-----------------------------------------------
// 打印变量
(gdb) print (p)
-----------------------------------------------
// 终止调试
(gdb) quit (q)	
-----------------------------------------------
// 显示调用堆栈
	// 显示当前执行线程
	bt
	// 跳转线程
	t + 线程号
	// 显示当前进程所有线程
	thread apply all bt

调试示范

为上述的case_2进行gdb调试分析:

不打断点,直接r运行:

在这里插入图片描述

发现直接锁死,Ctrl + c退出,打断点:

在这里插入图片描述

重新运行:
在这里插入图片描述
查看堆栈:

在这里插入图片描述
查看互斥锁信息:
在这里插入图片描述


死锁的必要条件

  • 互斥条件:
    一个互斥锁,同一时间只能被一个线程持有(属性条件,无法改变);

  • 不可剥夺:
    线程获得互斥锁后,只能自己释放,其他线程不能释放(属性条件,无法改变);

  • 循环等待:
    所有的线程都在等待一个锁,而这个锁被另一个线程所持有,且这种关系形成一个闭环;

  • 请求与保持:
    一个线程拿到了部分锁,若还需要锁,并不会释放已获得的锁,而是阻塞等待;

  • 上述四个条件须同时满足,才会发生死锁;


死锁的预防措施

在这里插入图片描述


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值