linux 下死锁情况分析

发布时间 2023-10-25 10:54:26作者: 小海哥哥de

一、死锁代码

#include <iostream>
#include <thread>
#include <mutex>

using namespace std;

mutex mt1;
mutex mt2;

void thread1(){
	cout << "thread1 begin" << endl;

	lock_guard<mutex> guard1(mt1);
	this_thread::sleep_for(chrono::seconds(1));
	lock_guard<mutex> guard2(mt2);

	cout << "thread1 end" << endl;
}

void thread2() {
	cout << "thread2 begin" << endl;

	lock_guard<mutex> guard2(mt2);
	this_thread::sleep_for(chrono::seconds(2));
	lock_guard<mutex> guard1(mt1);

	cout << "thread2 end" << endl;
}


int main()
{
	thread th1(thread1);
	thread th2(thread2);
	th1.join();
	th2.join();
	
	cout << "program end" << endl;
    return 0;
}

运行情况:

[root@Desktop-578c miyao]# g++ main.cpp -std=c++11 -lpthread -o thread
[root@Desktop-578c miyao]# ./thread
thread1 begin
thread2 begin

二、通过gdb查看线程情况

  • 2.1 查找进程id
[root@Desktop-578c ~]# ps -ef | grep thread
root           2       0  0 10月12 ?      00:00:00 [kthreadd]
root      836247  835170  0 10:17 pts/0    00:00:00 ./thread
root      836747  836202  0 10:25 pts/1    00:00:00 grep thread
  • 2.2 (1)gdb attach:attach到进程上,(2)info threads:显示所有线程,(3)thread apply all bt:显示线程详细信息,可以看出thread2和thread3都再mutex上,符合死锁特征。
[root@Desktop-578c ~]# gdb attach 836247
GNU gdb (GDB) EulerOS 8.3.1-11.ky10
Copyright (C) 2019 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "aarch64-kylin-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
attach: 没有那个文件或目录.
Attaching to process 836247
[New LWP 836248]
[New LWP 836249]

warning: File "/usr/lib64/libthread_db-1.0.so" auto-loading has been declined by your `auto-load safe-path' set to "$debugdir:$datadir/auto-load".
To enable execution of this file add
	add-auto-load-safe-path /usr/lib64/libthread_db-1.0.so
line to your configuration file "/root/.gdbinit".
To completely disable this security protection add
	set auto-load safe-path /
line to your configuration file "/root/.gdbinit".
For more information about this security protection see the
"Auto-loading safe path" section in the GDB manual.  E.g., run from the shell:
	info "(gdb)Auto-loading safe path"

warning: Unable to find libthread_db matching inferior's thread library, thread debugging will not be available.

warning: File "/usr/lib64/libthread_db-1.0.so" auto-loading has been declined by your `auto-load safe-path' set to "$debugdir:$datadir/auto-load".

warning: Unable to find libthread_db matching inferior's thread library, thread debugging will not be available.
0x0000fffe1ded9b3c in ?? () from /lib64/libpthread.so.0
Missing separate debuginfos, use: dnf debuginfo-install glibc-2.28-36.1.p09.ky10.aarch64 libgcc-7.3.0-20190804.h30.ky10.aarch64 libstdc++-7.3.0-20190804.h30.p03.ky10.aarch64
(gdb) info threads
  Id   Target Id           Frame 
* 1    LWP 836247 "thread" 0x0000fffe1ded9b3c in ?? () from /lib64/libpthread.so.0
  2    LWP 836248 "thread" 0x0000fffe1dee21dc in ?? () from /lib64/libpthread.so.0
  3    LWP 836249 "thread" 0x0000fffe1dee21dc in ?? () from /lib64/libpthread.so.0
(gdb) thread apply all bt

Thread 3 (LWP 836249):
#0  0x0000fffe1dee21dc in ?? () from /lib64/libpthread.so.0
#1  0x0000fffe1dedb060 in pthread_mutex_lock () from /lib64/libpthread.so.0
#2  0x000000000040100c in __gthread_mutex_lock(pthread_mutex_t*) ()
#3  0x0000000000401458 in std::mutex::lock() ()
#4  0x0000000000401504 in std::lock_guard<std::mutex>::lock_guard(std::mutex&) ()
#5  0x00000000004011b0 in thread2() ()
#6  0x00000000004019fc in void std::__invoke_impl<void, void (*)()>(std::__invoke_other, void (*&&)()) ()
#7  0x00000000004017bc in std::__invoke_result<void (*)()>::type std::__invoke<void (*)()>(void (*&&)()) ()
#8  0x0000000000401f2c in decltype (__invoke((_S_declval<0ul>)())) std::thread::_Invoker<std::tuple<void (*)()> >::_M_invoke<0ul>(std::_Index_tuple<0ul>) ()
#9  0x0000000000401f00 in std::thread::_Invoker<std::tuple<void (*)()> >::operator()() ()
#10 0x0000000000401ee0 in std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (*)()> > >::_M_run() ()
#11 0x0000fffe1ddde134 in ?? () from /lib64/libstdc++.so.6
#12 0x0000fffe1ded88cc in ?? () from /lib64/libpthread.so.0
#13 0x0000fffe1db59cac in ?? () from /lib64/libc.so.6

Thread 2 (LWP 836248):
#0  0x0000fffe1dee21dc in ?? () from /lib64/libpthread.so.0
#1  0x0000fffe1dedb060 in pthread_mutex_lock () from /lib64/libpthread.so.0
#2  0x000000000040100c in __gthread_mutex_lock(pthread_mutex_t*) ()
#3  0x0000000000401458 in std::mutex::lock() ()
#4  0x0000000000401504 in std::lock_guard<std::mutex>::lock_guard(std::mutex&) ()
#5  0x00000000004010cc in thread1() ()
#6  0x00000000004019fc in void std::__invoke_impl<void, void (*)()>(std::__invoke_other, void (*&&)()) ()
#7  0x00000000004017bc in std::__invoke_result<void (*)()>::type std::__invoke<void (*)()>(void (*&&)()) ()
#8  0x0000000000401f2c in decltype (__invoke((_S_declval<0ul>)())) std::thread::_Invoker<std::tuple<void (*)()> >::_M_invoke<0ul>(std::_Index_tuple<0ul>) ()
#9  0x0000000000401f00 in std::thread::_Invoker<std::tuple<void (*)()> >::operator()() ()
#10 0x0000000000401ee0 in std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (*)()> > >::_M_run() ()
#11 0x0000fffe1ddde134 in ?? () from /lib64/libstdc++.so.6
#12 0x0000fffe1ded88cc in ?? () from /lib64/libpthread.so.0
#13 0x0000fffe1db59cac in ?? () from /lib64/libc.so.6

Thread 1 (LWP 836247):
#0  0x0000fffe1ded9b3c in ?? () from /lib64/libpthread.so.0
#1  0x0000fffe1ddde400 in std::thread::join() () from /lib64/libstdc++.so.6
#2  0x0000000000401254 in main ()
(gdb) q
A debugging session is active.

	Inferior 1 [process 836247] will be detached.

Quit anyway? (y or n) y
Detaching from program: /root/miyao/thread, process 836247
[Inferior 1 (process 836247) detached]

三、CPU消耗情况

  • 通过ps查看CPU消耗情况,可以看出此时cpu并没有很高。通过top同样看不到cpu很高的情况。
[root@Desktop-578c ~]# ps -ef | grep thread
root           2       0  0 10月12 ?      00:00:00 [kthreadd]
root      836247  835170  0 10:17 pts/0    00:00:00 ./thread
root      837838  836202  0 10:42 pts/1    00:00:00 grep thread

ps命令每列的含义:

UID: 该进程执行的用户id
PID: 进程id
PPID: 该进程的父级进程id,如果一个程序的父级进程找不到,该程序的进程被称为僵尸进程
C: cpu的占用率,形式是百分数(%)
STIME: 进程的启动时间
TTY: 终端设备,发起该进程的设备识别符号,如果显示‘ ?’表示该进程并不是由终端发起
TIME: 进程的执行时间
CMD: 该进程的名称或对应的路径

资料:
https://blog.csdn.net/KevinChen2019/article/details/119697489
https://mp.weixin.qq.com/s?__biz=MzA3NzI1Njk1MQ==&mid=2648577503&idx=1&sn=dab3d52ccb60ade7f5565f7a47c6276e&chksm=877e7447b009fd51757a476a7da693597e24cb19de8ca89b370b80cbf1f476c617fbe91a9fd0&scene=27
https://blog.csdn.net/m0_72303088/article/details/131128937