面试题答案
一键面试- 使用互斥锁(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;
}
- 结合条件变量(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;
}
通过上述方法,利用互斥锁保证同一时间只有一个线程能修改共享数据,结合条件变量可以在数据更新完成后通知其他线程安全地读取,从而避免其他线程读取到错误的中间状态数据。