实现思路
- 共享数据结构:定义一个共享缓冲区用于生产者生产数据和消费者消费数据。
- 信号量:使用信号量来控制对共享缓冲区的访问。一个信号量用于表示缓冲区中的空闲槽位(empty),另一个用于表示缓冲区中的已占用槽位(full),还需要一个互斥信号量(mutex)来保证对共享缓冲区的互斥访问。
- 生产者:生产者线程获取empty信号量(表示有空闲槽位),然后获取mutex互斥信号量以安全访问共享缓冲区,生产数据放入缓冲区,释放mutex,再释放full信号量(表示有新数据)。
- 消费者:消费者线程获取full信号量(表示有数据),获取mutex互斥信号量以安全访问共享缓冲区,从缓冲区消费数据,释放mutex,再释放empty信号量(表示有空闲槽位)。
关键代码片段
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#define BUFFER_SIZE 5
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) {
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); // 通知缓冲区有新数据
item++;
}
return NULL;
}
// 消费者函数
void* consumer(void* arg) {
while (1) {
sem_wait(&full); // 等待缓冲区有数据
sem_wait(&mutex); // 进入临界区
int 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;
}