设计一个生产者-消费者进程同步
时间: 2024-02-15 15:02:47 浏览: 25
PV操作解决生产者-消费者问题
生产者-消费者问题是一个经典的多线程同步问题,解决这个问题的方法有多种,其中最常见的方法是使用信号量机制。下面是一个基于信号量的生产者-消费者进程同步的示例代码(使用C语言编写):
```
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#define BUFFER_SIZE 10 // 缓冲池大小
#define PRODUCER_NUM 5 // 生产者数量
#define CONSUMER_NUM 5 // 消费者数量
#define MAX_SLEEP_TIME 3 // 生产者和消费者的最大睡眠时间
sem_t mutex, empty, full; // 三个信号量
int buffer[BUFFER_SIZE]; // 缓冲池
int in = 0, out = 0; // 缓冲池的读写指针
void *producer(void *arg) {
int id = *(int *)arg;
while (1) {
// 生产者睡眠一段时间
sleep(rand() % MAX_SLEEP_TIME + 1);
// 生产一个产品
int product = rand() % 100;
// 等待empty信号量
sem_wait(&empty);
// 等待mutex信号量
sem_wait(&mutex);
// 将产品放入缓冲池
buffer[in] = product;
printf("Producer %d produce product %d\n", id, product);
in = (in + 1) % BUFFER_SIZE;
// 释放mutex信号量
sem_post(&mutex);
// 发送full信号量
sem_post(&full);
}
pthread_exit(NULL);
}
void *consumer(void *arg) {
int id = *(int *)arg;
while (1) {
// 消费者睡眠一段时间
sleep(rand() % MAX_SLEEP_TIME + 1);
// 等待full信号量
sem_wait(&full);
// 等待mutex信号量
sem_wait(&mutex);
// 从缓冲池中取出一个产品
int product = buffer[out];
printf("Consumer %d consume product %d\n", id, product);
out = (out + 1) % BUFFER_SIZE;
// 释放mutex信号量
sem_post(&mutex);
// 发送empty信号量
sem_post(&empty);
}
pthread_exit(NULL);
}
int main() {
sem_init(&mutex, 0, 1);
sem_init(&empty, 0, BUFFER_SIZE);
sem_init(&full, 0, 0);
pthread_t producers[PRODUCER_NUM], consumers[CONSUMER_NUM];
int producer_ids[PRODUCER_NUM], consumer_ids[CONSUMER_NUM];
// 创建生产者线程
for (int i = 0; i < PRODUCER_NUM; i++) {
producer_ids[i] = i;
pthread_create(&producers[i], NULL, producer, &producer_ids[i]);
}
// 创建消费者线程
for (int i = 0; i < CONSUMER_NUM; i++) {
consumer_ids[i] = i;
pthread_create(&consumers[i], NULL, consumer, &consumer_ids[i]);
}
// 等待所有线程退出
for (int i = 0; i < PRODUCER_NUM; i++) {
pthread_join(producers[i], NULL);
}
for (int i = 0; i < CONSUMER_NUM; i++) {
pthread_join(consumers[i], NULL);
}
sem_destroy(&mutex);
sem_destroy(&empty);
sem_destroy(&full);
return 0;
}
```
在上面的代码中,我们定义了三个信号量:mutex、empty和full。mutex信号量用于互斥地访问缓冲池,empty信号量用于表示缓冲池中还有多少空位可以放置产品,full信号量用于表示缓冲池中还有多少产品可以被消费。每个生产者线程在生产一个产品之前先等待empty信号量,表示缓冲池中还有空位可以放置产品;然后等待mutex信号量,表示它要进入临界区(访问缓冲池);在生产完一个产品后,释放mutex信号量,表示它退出临界区;最后发送full信号量,表示缓冲池中又多了一个产品可以被消费。每个消费者线程在消费一个产品之前先等待full信号量,表示缓冲池中有产品可以被消费;然后等待mutex信号量,表示它要进入临界区(访问缓冲池);在消费完一个产品后,释放mutex信号量,表示它退出临界区;最后发送empty信号量,表示缓冲池中又多了一个空位可以放置产品。这样,就可以保证生产者和消费者之间的同步和互斥了。
阅读全文