(1)编程实现生产者-消费者问题的模拟(建议用C语言编写源代码)。 基本要求: (1)生产者消费者对缓冲区进行互斥操作。 (2)缓冲区大小为10,缓冲区满则不允许生产者生产数据,缓冲区空则不允许消费者消费数据。 (3)生产者消费者各循环操作10次
时间: 2023-12-19 20:07:29 浏览: 126
以下是一个基于信号量解决生产者-消费者问题的模拟程序,使用C语言编写。
```c
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#define BUFFER_SIZE 10
#define PRODUCER_NUM 3
#define CONSUMER_NUM 2
int buffer[BUFFER_SIZE];
int in = 0, out = 0;
sem_t empty, full, mutex;
void* producer(void* arg) {
int id = *(int*)arg;
int i, item;
for (i = 0; i < 10; i++) {
item = rand() % 100;
sem_wait(&empty);
sem_wait(&mutex);
buffer[in] = item;
printf("Producer %d produced item: %d\n", id, item);
in = (in + 1) % BUFFER_SIZE;
sem_post(&mutex);
sem_post(&full);
}
pthread_exit(NULL);
}
void* consumer(void* arg) {
int id = *(int*)arg;
int i, item;
for (i = 0; i < 10; i++) {
sem_wait(&full);
sem_wait(&mutex);
item = buffer[out];
printf("Consumer %d consumed item: %d\n", id, item);
out = (out + 1) % BUFFER_SIZE;
sem_post(&mutex);
sem_post(&empty);
}
pthread_exit(NULL);
}
int main() {
int i, ret;
pthread_t producers[PRODUCER_NUM], consumers[CONSUMER_NUM];
int producer_ids[PRODUCER_NUM], consumer_ids[CONSUMER_NUM];
srand(time(NULL));
sem_init(&empty, 0, BUFFER_SIZE);
sem_init(&full, 0, 0);
sem_init(&mutex, 0, 1);
for (i = 0; i < PRODUCER_NUM; i++) {
producer_ids[i] = i;
ret = pthread_create(&producers[i], NULL, producer, &producer_ids[i]);
if (ret != 0) {
printf("Error: producer %d creation failed.\n", i);
exit(EXIT_FAILURE);
}
}
for (i = 0; i < CONSUMER_NUM; i++) {
consumer_ids[i] = i;
ret = pthread_create(&consumers[i], NULL, consumer, &consumer_ids[i]);
if (ret != 0) {
printf("Error: consumer %d creation failed.\n", i);
exit(EXIT_FAILURE);
}
}
for (i = 0; i < PRODUCER_NUM; i++) {
ret = pthread_join(producers[i], NULL);
if (ret != 0) {
printf("Error: producer %d join failed.\n", i);
exit(EXIT_FAILURE);
}
}
for (i = 0; i < CONSUMER_NUM; i++) {
ret = pthread_join(consumers[i], NULL);
if (ret != 0) {
printf("Error: consumer %d join failed.\n", i);
exit(EXIT_FAILURE);
}
}
sem_destroy(&empty);
sem_destroy(&full);
sem_destroy(&mutex);
return 0;
}
```
该程序定义了三个信号量:`empty`表示缓冲区剩余空位数量,初始值为`BUFFER_SIZE`;`full`表示缓冲区已占用空位数量,初始值为0;`mutex`为互斥信号量,保证同一时间只有一个线程访问缓冲区。
生产者线程循环10次,每次生产一个随机数,若缓冲区未满则将随机数放入缓冲区中,并输出生产者ID和生产的数据项;否则等待`empty`信号量,直到有空位为止。生产完毕后释放`mutex`信号量,并将`full`信号量加1。
消费者线程循环10次,每次从缓冲区中取出一个数据项,若缓冲区非空则取出数据项,并输出消费者ID和消费的数据项;否则等待`full`信号量,直到有数据项为止。消费完毕后释放`mutex`信号量,并将`empty`信号量加1。
在主函数中,创建`PRODUCER_NUM`个生产者线程和`CONSUMER_NUM`个消费者线程。使用`pthread_join`等待所有线程执行完毕。最后销毁信号量并返回0。
运行程序,可以得到类似下面的输出:
```
Producer 0 produced item: 39
Producer 1 produced item: 4
Consumer 0 consumed item: 39
Consumer 1 consumed item: 4
Producer 2 produced item: 12
Producer 0 produced item: 75
Consumer 0 consumed item: 12
Producer 1 produced item: 31
Producer 2 produced item: 7
Consumer 1 consumed item: 75
Consumer 0 consumed item: 31
Producer 0 produced item: 50
Consumer 1 consumed item: 7
Producer 1 produced item: 8
Producer 2 produced item: 70
Consumer 0 consumed item: 50
Producer 0 produced item: 2
Consumer 1 consumed item: 8
Producer 1 produced item: 92
Consumer 0 consumed item: 70
Producer 2 produced item: 33
Consumer 1 consumed item: 2
Producer 0 produced item: 44
Consumer 0 consumed item: 92
Producer 1 produced item: 61
Consumer 1 consumed item: 33
Producer 2 produced item: 83
Consumer 0 consumed item: 44
Consumer 1 consumed item: 61
Consumer 0 consumed item: 83
```
阅读全文