面试题答案
一键面试信号量机制基本原理
信号量(Semaphore)是一个整型变量,它通过一个计数器来控制对共享资源的访问。信号量的值表示当前可用的共享资源数量。当一个进程想要访问共享资源时,它需要先获取信号量。如果信号量的值大于 0,那么进程可以获取信号量,同时信号量的值减 1;如果信号量的值为 0,说明共享资源已被占用,进程需要等待,直到信号量的值变为大于 0 时才能获取。当进程使用完共享资源后,会释放信号量,信号量的值加 1。
使用信号量实现进程同步示例(以 C 语言结合 POSIX 信号量为例)
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#define BUFFER_SIZE 10
int buffer[BUFFER_SIZE];
int in = 0;
int out = 0;
sem_t empty;
sem_t full;
sem_t mutex;
void* producer(void* arg) {
int item = 0;
while (1) {
item++;
sem_wait(&empty); // 等待缓冲区有空闲位置
sem_wait(&mutex); // 进入临界区
buffer[in] = item;
printf("Produced: %d\n", item);
in = (in + 1) % BUFFER_SIZE;
sem_post(&mutex); // 离开临界区
sem_post(&full); // 通知缓冲区有新数据
}
return NULL;
}
void* consumer(void* arg) {
int item;
while (1) {
sem_wait(&full); // 等待缓冲区有数据
sem_wait(&mutex); // 进入临界区
item = buffer[out];
printf("Consumed: %d\n", item);
out = (out + 1) % BUFFER_SIZE;
sem_post(&mutex); // 离开临界区
sem_post(&empty); // 通知缓冲区有空闲位置
}
return NULL;
}
int main() {
pthread_t producer_thread, consumer_thread;
sem_init(&empty, 0, BUFFER_SIZE);
sem_init(&full, 0, 0);
sem_init(&mutex, 0, 1);
pthread_create(&producer_thread, NULL, producer, NULL);
pthread_create(&consumer_thread, NULL, consumer, NULL);
pthread_join(producer_thread, NULL);
pthread_join(consumer_thread, NULL);
sem_destroy(&empty);
sem_destroy(&full);
sem_destroy(&mutex);
return 0;
}
在上述代码中:
empty
信号量表示缓冲区中的空闲位置数量,初始值为BUFFER_SIZE
。full
信号量表示缓冲区中的数据数量,初始值为 0。mutex
信号量用于保证对共享缓冲区的互斥访问,初始值为 1。- 生产者线程在生产数据前先获取
empty
信号量,确保缓冲区有空闲位置,然后获取mutex
信号量进入临界区,将数据放入缓冲区后释放mutex
和full
信号量。 - 消费者线程在消费数据前先获取
full
信号量,确保缓冲区有数据,然后获取mutex
信号量进入临界区,从缓冲区取出数据后释放mutex
和empty
信号量。这样就实现了生产者 - 消费者之间的同步。