MST

星途 面试题库

面试题:C语言中Linux互斥锁嵌套使用的基本问题

在Linux环境下使用C语言进行互斥锁嵌套时,可能会遇到死锁问题。请描述死锁产生的原因,并给出一种避免死锁的方法,同时用代码示例展示如何正确嵌套使用互斥锁来避免死锁。
36.4万 热度难度
编程语言C

知识考点

AI 面试

面试题答案

一键面试

死锁产生的原因

在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_function1thread_function2都按照相同的顺序获取mutex1mutex2,从而避免了死锁。在获取完互斥锁后执行临界区代码,然后以相反的顺序释放互斥锁。