面试题答案
一键面试互斥锁(mutex)
- 作用:互斥锁用于保证在同一时间只有一个线程能够访问共享资源,防止多个线程同时对共享资源进行读写操作而导致数据不一致等问题。它通过加锁和解锁操作来实现对共享资源的保护。
- 使用场景:当多个线程需要访问共享资源,并且该共享资源不允许同时被多个线程访问时,使用互斥锁。例如多个线程对同一个全局变量进行读写操作的场景。
条件变量(condition variable)
- 作用:条件变量用于线程间的同步通信,它可以让线程等待某个条件满足后再继续执行。条件变量通常和互斥锁一起使用,线程在等待条件变量时会释放持有的互斥锁,当条件满足时,被唤醒的线程会重新获取互斥锁。
- 使用场景:当线程需要等待某个特定条件出现才能继续执行时,例如生产者 - 消费者模型中,消费者线程需要等待生产者线程生产出数据后才能消费,此时可以使用条件变量。
C语言代码示例(生产者 - 消费者模型)
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#define BUFFER_SIZE 5
int buffer[BUFFER_SIZE];
int in = 0;
int out = 0;
pthread_mutex_t mutex;
pthread_cond_t cond_producer;
pthread_cond_t cond_consumer;
void *producer(void *arg) {
int item = 0;
while (1) {
pthread_mutex_lock(&mutex);
while ((in + 1) % BUFFER_SIZE == out) {
pthread_cond_wait(&cond_producer, &mutex);
}
buffer[in] = item++;
printf("Produced: %d\n", buffer[in]);
in = (in + 1) % BUFFER_SIZE;
pthread_cond_signal(&cond_consumer);
pthread_mutex_unlock(&mutex);
}
pthread_exit(NULL);
}
void *consumer(void *arg) {
while (1) {
pthread_mutex_lock(&mutex);
while (in == out) {
pthread_cond_wait(&cond_consumer, &mutex);
}
int item = buffer[out];
printf("Consumed: %d\n", item);
out = (out + 1) % BUFFER_SIZE;
pthread_cond_signal(&cond_producer);
pthread_mutex_unlock(&mutex);
}
pthread_exit(NULL);
}
int main() {
pthread_t tid_producer, tid_consumer;
pthread_mutex_init(&mutex, NULL);
pthread_cond_init(&cond_producer, NULL);
pthread_cond_init(&cond_consumer, NULL);
pthread_create(&tid_producer, NULL, producer, NULL);
pthread_create(&tid_consumer, NULL, consumer, NULL);
pthread_join(tid_producer, NULL);
pthread_join(tid_consumer, NULL);
pthread_mutex_destroy(&mutex);
pthread_cond_destroy(&cond_producer);
pthread_cond_destroy(&cond_consumer);
return 0;
}
在上述代码中:
- 互斥锁
mutex
用于保护共享缓冲区buffer
,防止多个线程同时访问。 - 条件变量
cond_producer
用于生产者线程等待缓冲区有空间时被唤醒。 - 条件变量
cond_consumer
用于消费者线程等待缓冲区有数据时被唤醒。 - 生产者线程不断生产数据并放入缓冲区,当缓冲区满时等待
cond_producer
条件变量。 - 消费者线程不断从缓冲区取出数据,当缓冲区空时等待
cond_consumer
条件变量。