一、调试代码如下 来源 阅码场https://www.yomocode.com/
void *child1(void *arg)
{
while(1){
pthread_mutex_lock(&mutex_1);
sleep(3);
pthread_mutex_lock(&mutex_2);
printf("thread 1 get running \n");
pthread_mutex_unlock(&mutex_2);
pthread_mutex_unlock(&mutex_1);
sleep(5);
}
}
void *child2(void *arg)
{
while(1){
pthread_mutex_lock(&mutex_2);
pthread_mutex_lock(&mutex_1);
printf("thread 2 get running \n");
pthread_mutex_unlock(&mutex_1);
pthread_mutex_unlock(&mutex_2);
sleep(5);
}
}
代码会如下造成死锁现象
LWP 4860 mutex_2 __owner = 4861
LWP 4861 mutex_1 __owner = 4860
线程4860再等4861 线程4861在等4860所以造成死锁
调试如下
一个终端 执行程序
arsenal@arsenal-kernel:~/pthread/day2$ ./a.out
另一个终端gdb 调试
arsenal@arsenal-kernel:~/pthread/day2$
arsenal@arsenal-kernel:~/pthread/day2$ sudo gdb -q -p `pidof a.out`
Attaching to process 4859
[New LWP 4860]
[New LWP 4861]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
0x00007f68bb6e530d in nanosleep () at ../sysdeps/unix/syscall-template.S:84
84 ../sysdeps/unix/syscall-template.S: 没有那个文件或目录.
(gdb)
(gdb) thread i //看所有线程
Invalid thread ID: i
(gdb) i threads
Id Target Id Frame
* 1 Thread 0x7f68bbe09700 (LWP 4859) "a.out" 0x00007f68bb6e530d in nanosleep
() at ../sysdeps/unix/syscall-template.S:84
2 Thread 0x7f68bb618700 (LWP 4860) "a.out" __lll_lock_wait ()
at ../sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:135
3 Thread 0x7f68bae17700 (LWP 4861) "a.out" __lll_lock_wait ()
at ../sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:135
(gdb) thread 2 进入线程2
[Switching to thread 2 (Thread 0x7f68bb618700 (LWP 4860))] //该线程号为4860
#0 __lll_lock_wait () at ../sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:135
135 ../sysdeps/unix/sysv/linux/x86_64/lowlevellock.S: 没有那个文件或目录.
(gdb) bt
#0 __lll_lock_wait () at ../sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:135
#1 0x00007f68bb9ecdbd in __GI___pthread_mutex_lock (mutex=0x6010c0 <mutex_2>)
at ../nptl/pthread_mutex_lock.c:80
#2 0x00000000004007b0 in child1 (arg=0x0) at deadlock.c:12
#3 0x00007f68bb9ea6ba in start_thread (arg=0x7f68bb618700)
at pthread_create.c:333
#4 0x00007f68bb72041d in clone ()
at ../sysdeps/unix/sysv/linux/x86_64/clone.S:109
(gdb) l child1
3 #include <unistd.h>
4 pthread_mutex_t mutex_1;
5 pthread_mutex_t mutex_2;
6
7 void *child1(void *arg)
8 {
9 while(1){
10 pthread_mutex_lock(&mutex_1);
11 sleep(3);
12 pthread_mutex_lock(&mutex_2);
(gdb) p mutex
No symbol "mutex" in current context.
(gdb) p mutex_2
$1 = {__data = {__lock = 2, __count = 0, __owner = 4861, __nusers = 1,
__kind = 0, __spins = 0, __elision = 0, __list = {__prev = 0x0,
__next = 0x0}},
__size = "\002\000\000\000\000\000\000\000\375\022\000\000\001", '\000' <repeats 26 times>, __align = 2}
(gdb) thread 3
[Switching to thread 3 (Thread 0x7f68bae17700 (LWP 4861))]
#0 __lll_lock_wait () at ../sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:135
135 ../sysdeps/unix/sysv/linux/x86_64/lowlevellock.S: 没有那个文件或目录.
(gdb) bt
#0 __lll_lock_wait () at ../sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:135
#1 0x00007f68bb9ecdbd in __GI___pthread_mutex_lock (mutex=0x601080 <mutex_1>)
at ../nptl/pthread_mutex_lock.c:80
#2 0x00000000004007fa in child2 (arg=0x0) at deadlock.c:24
#3 0x00007f68bb9ea6ba in start_thread (arg=0x7f68bae17700)
at pthread_create.c:333
#4 0x00007f68bb72041d in clone ()
at ../sysdeps/unix/sysv/linux/x86_64/clone.S:109
(gdb) l child2
16 sleep(5);
17 }
18 }
19
20 void *child2(void *arg)
21 {
22 while(1){
23 pthread_mutex_lock(&mutex_2);
24 pthread_mutex_lock(&mutex_1);
25 printf("thread 2 get running \n");
(gdb) p mutex_1
$2 = {__data = {__lock = 2, __count = 0, __owner = 4860, __nusers = 1,
__kind = 0, __spins = 0, __elision = 0, __list = {__prev = 0x0,
__next = 0x0}},
__size = "\002\000\000\000\000\000\000\000\374\022\000\000\001", '\000' <repeats 26 times>, __align = 2}
(gdb)
解决方法:
加锁顺序要相同,先拿到锁的后释放锁