关于死锁那些事

来源:

【Linux】线程安全:死锁(附加gdb调试分析)_gdb查看死锁-CSDN博客

死锁的产生场景

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

模拟代码:

结果分析:

死锁的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运行:

死锁的必要条件


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

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

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

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

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

死锁的预防措施
 

本文来源:

【Linux】线程安全:死锁(附加gdb调试分析)_gdb查看死锁-CSDN博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值