设计进程同步算法,使用P/V(wait/signal)操作模拟解决进程中经典同步问题。假设有一个生产者和一个消费者,缓冲区可以存放产品,生产者不断生产产品并存入缓冲区,消费者不断从缓冲区中取出产品并消费,设计代码并运行实现结果。
时间: 2024-03-20 18:39:20 浏览: 25
以下是一个简单的生产者-消费者问题的解决方案:
```
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#define BUFFER_SIZE 5
#define PRODUCER_NUM 2
#define CONSUMER_NUM 2
#define ITEM_COUNT 10
int buffer[BUFFER_SIZE];
int in = 0;
int out = 0;
pthread_mutex_t mutex;
sem_t full;
sem_t empty;
void *producer(void *arg) {
int i, item;
int id = *(int *) arg;
for (i = 0; i < ITEM_COUNT; i++) {
item = rand() % 100; // 生产一个随机数
sem_wait(&empty); // 等待空缓冲区
pthread_mutex_lock(&mutex); // 互斥访问缓冲区
buffer[in] = item; // 存入缓冲区
printf("Producer %d produced item %d at buffer[%d]\n", id, item, in);
in = (in + 1) % BUFFER_SIZE; // 更新指针
pthread_mutex_unlock(&mutex); // 解锁缓冲区
sem_post(&full); // 发送满缓冲区信号
}
}
void *consumer(void *arg) {
int i, item;
int id = *(int *) arg;
for (i = 0; i < ITEM_COUNT; i++) {
sem_wait(&full); // 等待满缓冲区
pthread_mutex_lock(&mutex); // 互斥访问缓冲区
item = buffer[out]; // 取出缓冲区的一个元素
printf("Consumer %d consumed item %d from buffer[%d]\n", id, item, out);
out = (out + 1) % BUFFER_SIZE; // 更新指针
pthread_mutex_unlock(&mutex); // 解锁缓冲区
sem_post(&empty); // 发送空缓冲区信号
}
}
int main() {
pthread_t producers[PRODUCER_NUM], consumers[CONSUMER_NUM];
int i, id[PRODUCER_NUM + CONSUMER_NUM];
pthread_mutex_init(&mutex, NULL);
sem_init(&full, 0, 0);
sem_init(&empty, 0, BUFFER_SIZE);
for (i = 0; i < PRODUCER_NUM; i++) {
id[i] = i;
pthread_create(&producers[i], NULL, producer, &id[i]);
}
for (i = 0; i < CONSUMER_NUM; i++) {
id[PRODUCER_NUM + i] = i;
pthread_create(&consumers[i], NULL, consumer, &id[PRODUCER_NUM + i]);
}
for (i = 0; i < PRODUCER_NUM; i++) {
pthread_join(producers[i], NULL);
}
for (i = 0; i < CONSUMER_NUM; i++) {
pthread_join(consumers[i], NULL);
}
pthread_mutex_destroy(&mutex);
sem_destroy(&full);
sem_destroy(&empty);
return 0;
}
```
上述代码中,我们使用了互斥锁和信号量来实现进程同步。生产者进程通过`sem_wait(&empty)`等待空缓冲区,当缓冲区满时,通过`sem_post(&full)`发送满缓冲区信号,唤醒消费者进程。消费者进程则通过`sem_wait(&full)`等待满缓冲区,当缓冲区为空时,通过`sem_post(&empty)`发送空缓冲区信号,唤醒生产者进程。同时,为了保证对缓冲区的互斥访问,我们使用了互斥锁`pthread_mutex_t mutex`来保护缓冲区的访问。
在以上代码的运行结果中,我们可以看到生产者和消费者进程交替执行,生产者不断生产随机数并存入缓冲区,消费者不断从缓冲区中取出随机数并消费,直到生产者和消费者均完成了指定数量的操作。
阅读全文