面试题答案
一键面试互斥锁、条件变量和信号量的作用及使用场景
-
互斥锁(Mutex)
- 作用:用于保护共享资源,确保在同一时间只有一个线程能够访问该资源,避免竞态条件(race condition)。它就像一把锁,线程获取锁(lock)后才能访问共享资源,访问完后释放锁(unlock)。
- 使用场景:当多个线程需要访问共享资源,且对共享资源的访问需要原子性操作时使用。例如多个线程对一个全局变量进行读写操作。
-
条件变量(Condition Variable)
- 作用:条件变量通常和互斥锁一起使用,用于线程间的同步。它允许线程等待某个条件满足,当条件满足时,等待在条件变量上的线程会被唤醒。
- 使用场景:当一个线程需要等待某个特定条件发生才能继续执行时,如生产者 - 消费者模型中,消费者线程需要等待生产者线程生产数据后才能消费。
-
信号量(Semaphore)
- 作用:信号量是一个计数器,它可以控制同时访问某个资源的线程数量。通过初始化信号量的值来设定允许访问资源的线程上限。
- 使用场景:当需要限制同时访问共享资源的线程数量时使用,比如连接池,限制同时使用的连接数。
使用互斥锁保护共享资源的简单代码
#include <pthread.h>
#include <stdio.h>
// 共享资源
int shared_variable = 0;
// 互斥锁
pthread_mutex_t mutex;
void* increment_shared_variable(void* arg) {
// 加锁
pthread_mutex_lock(&mutex);
shared_variable++;
printf("Thread incremented shared_variable to %d\n", shared_variable);
// 解锁
pthread_mutex_unlock(&mutex);
return NULL;
}
int main() {
pthread_t thread1, thread2;
// 初始化互斥锁
pthread_mutex_init(&mutex, NULL);
// 创建线程
pthread_create(&thread1, NULL, increment_shared_variable, NULL);
pthread_create(&thread2, NULL, increment_shared_variable, NULL);
// 等待线程结束
pthread_join(thread1, NULL);
pthread_join(thread2, NULL);
// 销毁互斥锁
pthread_mutex_destroy(&mutex);
return 0;
}
在上述代码中,我们定义了一个共享变量shared_variable
,并使用互斥锁mutex
来保护对它的访问。每个线程在访问shared_variable
之前先获取互斥锁,访问完成后释放互斥锁,从而确保了对共享变量的操作是线程安全的。