MST

星途 面试题库

面试题:C语言多线程错误处理之同步问题

在一个使用C语言编写的多线程程序中,多个线程会同时访问并修改共享数据。如果一个线程在修改共享数据过程中发生错误,如何保证其他线程不会读取到错误的中间状态数据?请结合互斥锁、条件变量等同步机制阐述你的解决方案,并给出关键代码片段。
15.7万 热度难度
编程语言C

知识考点

AI 面试

面试题答案

一键面试
  1. 使用互斥锁(Mutex)
    • 原理:互斥锁用于保护共享资源,同一时间只允许一个线程访问共享数据。当一个线程获取到互斥锁,其他线程就必须等待,直到该线程释放互斥锁。
    • 关键代码片段
#include <pthread.h>
#include <stdio.h>

// 定义共享数据
int shared_data = 0;
// 定义互斥锁
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

// 线程函数
void* thread_function(void* arg) {
    // 加锁
    pthread_mutex_lock(&mutex);
    // 模拟修改共享数据过程中可能发生错误
    int temp = shared_data;
    // 假设这里出现错误,如计算错误
    temp = temp + 1; 
    shared_data = temp;
    // 解锁
    pthread_mutex_unlock(&mutex);
    return NULL;
}

int main() {
    pthread_t thread;
    // 创建线程
    pthread_create(&thread, NULL, thread_function, NULL);
    // 等待线程结束
    pthread_join(thread, NULL);
    // 销毁互斥锁
    pthread_mutex_destroy(&mutex);
    return 0;
}
  1. 结合条件变量(Condition Variable)
    • 原理:条件变量通常与互斥锁一起使用。当共享数据达到某个条件时,线程可以通过条件变量通知其他等待的线程。在修改共享数据前,线程获取互斥锁,修改完成后,通过条件变量通知其他线程数据已更新。
    • 关键代码片段
#include <pthread.h>
#include <stdio.h>

// 定义共享数据
int shared_data = 0;
// 定义互斥锁
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
// 定义条件变量
pthread_cond_t cond_var = PTHREAD_COND_INITIALIZER;

// 线程函数
void* thread_function(void* arg) {
    // 加锁
    pthread_mutex_lock(&mutex);
    // 模拟修改共享数据过程中可能发生错误
    int temp = shared_data;
    // 假设这里出现错误,如计算错误
    temp = temp + 1; 
    shared_data = temp;
    // 通知其他线程数据已更新
    pthread_cond_signal(&cond_var);
    // 解锁
    pthread_mutex_unlock(&mutex);
    return NULL;
}

// 另一个线程函数用于读取共享数据
void* read_thread_function(void* arg) {
    // 加锁
    pthread_mutex_lock(&mutex);
    // 等待条件变量通知
    pthread_cond_wait(&cond_var, &mutex);
    // 此时共享数据已更新,安全读取
    printf("Shared data: %d\n", shared_data);
    // 解锁
    pthread_mutex_unlock(&mutex);
    return NULL;
}

int main() {
    pthread_t thread1, thread2;
    // 创建修改数据的线程
    pthread_create(&thread1, NULL, thread_function, NULL);
    // 创建读取数据的线程
    pthread_create(&thread2, NULL, read_thread_function, NULL);
    // 等待线程结束
    pthread_join(thread1, NULL);
    pthread_join(thread2, NULL);
    // 销毁互斥锁和条件变量
    pthread_mutex_destroy(&mutex);
    pthread_cond_destroy(&cond_var);
    return 0;
}

通过上述方法,利用互斥锁保证同一时间只有一个线程能修改共享数据,结合条件变量可以在数据更新完成后通知其他线程安全地读取,从而避免其他线程读取到错误的中间状态数据。