Linux死锁实验分析与总结
三、实验结果截图及分析
1. 实验代码
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t mutex2 = PTHREAD_MUTEX_INITIALIZER;void* producer(void* arg) {while (1) {pthread_mutex_lock(&mutex1);sleep(1);pthread_mutex_lock(&mutex2);printf("Producer is producing...\n");pthread_mutex_unlock(&mutex2);pthread_mutex_unlock(&mutex1);}return NULL;
}void* consumer(void* arg) {while (1) {pthread_mutex_lock(&mutex2);sleep(1);pthread_mutex_lock(&mutex1);printf("Consumer is consuming...\n");pthread_mutex_unlock(&mutex1);pthread_mutex_unlock(&mutex2);}return NULL;
}int main() {pthread_t tid1, tid2;pthread_create(&tid1, NULL, producer, NULL);pthread_create(&tid2, NULL, consumer, NULL);pthread_join(tid1, NULL);pthread_join(tid2, NULL);return 0;
}
2. 运行结果
程序运行后挂起,无输出。通过 Ctrl+C
终止后重新运行多次,现象一致。
3. 死锁分析
使用 pstack
查看进程堆栈:
$ ps aux | grep deadlock $ pstack <PID># 输出示例 Thread 2 (Thread 0x7f8a4b27e700 (LWP 12345)): #0 0x00007f8a4c6d4e32 in __GI___pthread_mutex_lock (mutex=0x55d8c0e02010 <mutex2>) at ../nptl/pthread_mutex_lock.c:67 #1 0x000055d8c0e0193a in consumer (arg=0x0) at deadlock.c:18 ...Thread 1 (Thread 0x7f8a4ba7f740 (LWP 12344)): #0 0x00007f8a4c6d4e32 in __GI___pthread_mutex_lock (mutex=0x55d8c0e02000 <mutex1>) at ../nptl/pthread_mutex_lock.c:67 #1 0x000055d8c0e018e6 in producer (arg=0x0) at deadlock.c:9 ...
分析:
-
生产者线程(Thread 1)持有
mutex1
,等待mutex2
。 -
消费者线程(Thread 2)持有
mutex2
,等待mutex1
。 -
两个线程互相等待对方释放锁,形成循环等待,导致死锁。
4. 死锁原因
-
锁顺序不一致:生产者先获取
mutex1
再mutex2
,消费者反之。 -
资源竞争:双方同时持有一个锁并请求对方持有的锁,导致永久阻塞。
四、总结
1. 实验问题及解决
-
问题1:死锁复现概率低。
解决:在锁操作间添加sleep(1)
增大竞争窗口。 -
问题2:工具使用不熟练。
解决:查阅pstack
和gdb
文档,熟悉多线程调试命令。
2. 心得体会
-
设计阶段:明确锁的获取顺序是避免死锁的关键。
-
调试技巧:堆栈跟踪工具能快速定位阻塞点,结合多次采样提高准确性。
-
理论实践结合:通过实际代码验证了循环等待导致死锁的原理。