记录c++ std::mutex AA死锁分析过程
源码
#include <thread>
#include <mutex>
#include <iostream>
int g_i = 0;
std::mutex g_i_mutex;
void safe_increment()
{
g_i_mutex.lock();
g_i_mutex.lock();
++g_i;
}
int main()
{
std::thread t1(safe_increment);
std::thread t2(safe_increment);
t1.join();
t2.join();
getchar();
return 0;
}
调试分析
-
编译连接,生成可执行程序main
user@dcs-04c2d773-0:/workspace/CPPProject$ g++ -g main.cpp -o main -lpthread -
运行可执行程序main,发现程序卡住
user@dcs-04c2d773-0:/workspace/CPPProject$ ./main -
查看程序的进程id,找到id为563
user@dcs-04c2d773-0:/workspace/CPPProject$ ps -aux | grep “main”
user 1 0.0 0.3 5728 3348 ? Ss 14:20 0:00 /bin/bash -c ?#!/bin/bash ?/.dcs/main & ?if [ “C++” == “HTML” ]; then ??PROJECT_ROOT=/workspace /usr/local/bin/tc-simple-web & ?fi ?sleep infinity ?
user 6 0.0 1.4 574992 15080 ? Sl 14:20 0:00 /.dcs/main
user 563 0.0 0.1 22096 1560 pts/2 Sl+ 14:40 0:00 ./main
user 656 0.0 0.0 5072 664 pts/3 S+ 14:43 0:00 grep main -
gdb挂住的进程
user@dcs-04c2d773-0:/workspace/CPPProject$ gdb -p 563
发现程序卡在join,对应代码中的第20行,即说明t1线程卡住。 -
查看线程信息
主线程为563,有2个子线程,id为565和566。两个子线程也在wait lock。 -
打印锁信息
发现mutex锁被565持有。
-
切换线程,查看堆栈信息
切换到线程565,相对id为2,查看堆栈,发现挂在第11行,即第二次加锁挂住。至此,就可以确认是AA锁导致挂死。
同时也可以推断出:线程566,肯定也加不到锁,挂在第10行。