面试题答案
一键面试设计思路
- 共享缓冲区:使用数组或链表来实现共享缓冲区,记录缓冲区的状态(如已占用的位置、总大小等)。
- 条件变量:
- 一个条件变量用于表示缓冲区为空的情况,当缓冲区为空时,消费者进程等待这个条件变量。
- 另一个条件变量用于表示缓冲区为满的情况,当缓冲区为满时,生产者进程等待这个条件变量。
- 互斥锁:为了保证对共享缓冲区的访问是线程安全的,需要使用互斥锁来保护共享资源。在访问共享缓冲区之前加锁,访问完之后解锁。
- 数据一致性:通过互斥锁来确保在同一时间只有一个进程可以访问共享缓冲区,避免数据竞争。同时,使用条件变量来保证生产者和消费者之间的同步,确保数据的正确读写。
关键代码片段(以C语言为例,基于POSIX线程库)
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#define BUFFER_SIZE 5
int buffer[BUFFER_SIZE];
int in = 0;
int out = 0;
int count = 0;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t not_full = PTHREAD_COND_INITIALIZER;
pthread_cond_t not_empty = PTHREAD_COND_INITIALIZER;
// 生产者函数
void* producer(void* arg) {
int item = *((int*)arg);
while (1) {
pthread_mutex_lock(&mutex);
while (count == BUFFER_SIZE) {
pthread_cond_wait(¬_full, &mutex);
}
buffer[in] = item;
printf("Produced: %d\n", item);
in = (in + 1) % BUFFER_SIZE;
count++;
pthread_cond_signal(¬_empty);
pthread_mutex_unlock(&mutex);
}
return NULL;
}
// 消费者函数
void* consumer(void* arg) {
while (1) {
pthread_mutex_lock(&mutex);
while (count == 0) {
pthread_cond_wait(¬_empty, &mutex);
}
int item = buffer[out];
printf("Consumed: %d\n", item);
out = (out + 1) % BUFFER_SIZE;
count--;
pthread_cond_signal(¬_full);
pthread_mutex_unlock(&mutex);
}
return NULL;
}
在主函数中可以创建生产者和消费者线程并传入相应参数,然后等待线程结束,释放资源:
int main() {
pthread_t producer_thread, consumer_thread;
int producer_item = 1;
int consumer_item = 1;
pthread_create(&producer_thread, NULL, producer, &producer_item);
pthread_create(&consumer_thread, NULL, consumer, &consumer_item);
pthread_join(producer_thread, NULL);
pthread_join(consumer_thread, NULL);
pthread_mutex_destroy(&mutex);
pthread_cond_destroy(¬_full);
pthread_cond_destroy(¬_empty);
return 0;
}