面试题答案
一键面试死锁产生的原因
在Linux环境下使用C语言进行互斥锁嵌套时,死锁产生的主要原因是多个线程以不同的顺序获取互斥锁。例如,线程A获取了互斥锁1,然后尝试获取互斥锁2;而线程B获取了互斥锁2,然后尝试获取互斥锁1。这样两个线程都在等待对方释放锁,从而陷入死锁状态。
避免死锁的方法
一种常见的避免死锁的方法是按照固定的顺序获取互斥锁。无论在哪个线程中,都始终以相同的顺序获取多个互斥锁,这样就不会出现循环等待的情况,从而避免死锁。
代码示例
#include <stdio.h>
#include <pthread.h>
// 定义两个互斥锁
pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t mutex2 = PTHREAD_MUTEX_INITIALIZER;
// 线程函数1
void* thread_function1(void* arg) {
// 始终先获取mutex1,再获取mutex2
pthread_mutex_lock(&mutex1);
printf("Thread 1 acquired mutex1\n");
pthread_mutex_lock(&mutex2);
printf("Thread 1 acquired mutex2\n");
// 执行临界区代码
printf("Thread 1 is in critical section\n");
// 释放互斥锁,顺序与获取顺序相反
pthread_mutex_unlock(&mutex2);
printf("Thread 1 released mutex2\n");
pthread_mutex_unlock(&mutex1);
printf("Thread 1 released mutex1\n");
return NULL;
}
// 线程函数2
void* thread_function2(void* arg) {
// 同样先获取mutex1,再获取mutex2
pthread_mutex_lock(&mutex1);
printf("Thread 2 acquired mutex1\n");
pthread_mutex_lock(&mutex2);
printf("Thread 2 acquired mutex2\n");
// 执行临界区代码
printf("Thread 2 is in critical section\n");
// 释放互斥锁,顺序与获取顺序相反
pthread_mutex_unlock(&mutex2);
printf("Thread 2 released mutex2\n");
pthread_mutex_unlock(&mutex1);
printf("Thread 2 released mutex1\n");
return NULL;
}
int main() {
pthread_t thread1, thread2;
// 创建线程
pthread_create(&thread1, NULL, thread_function1, NULL);
pthread_create(&thread2, NULL, thread_function2, NULL);
// 等待线程结束
pthread_join(thread1, NULL);
pthread_join(thread2, NULL);
// 销毁互斥锁
pthread_mutex_destroy(&mutex1);
pthread_mutex_destroy(&mutex2);
return 0;
}
在上述代码中,两个线程thread_function1
和thread_function2
都按照相同的顺序获取mutex1
和mutex2
,从而避免了死锁。在获取完互斥锁后执行临界区代码,然后以相反的顺序释放互斥锁。