实验目的:
通过编程实现生产者消费者模型来理解生产者-消费者这一经典同步问题,理解并能够应用信号量进行线程同步控制。
预期效果:
在linux中使用pthread库与semaphore库实现循环的存在三个生产者、一个消费者、产品缓冲区容量为5的模型。
实验思路:
首先分析在生产者消费者之间存在的同步问题,使用full和empty信号量来控制生产者与消费者行动的先后顺序。
然后分析对临界区资源进行访问时的互斥问题,在对临界区进行操作时,生产者与消费者之间均需要实现互斥锁。
对于生产者,我们采用 product[(p_count++)%5] = 1 来表示生产一个产品。
对于消费者,我们采用 product[(c_count++)%5] = 1 来表示消费一个产品
实验代码:
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <semaphore.h>
int product[5] = {0,0,0,0,0};
sem_t full;
sem_t empty;
sem_t mutex;
int p_count = 0;
int c_count = 0;
void showProductArray() {
printf("[");
for (int i = 0; i < 5; i++) {
printf("%d,",product[i]);
}
printf("]\n");
}
void* produce(void* args) {
while(1) {
sem_wait(&empty);
sem_wait(&mutex);
product[(p_count++)%5] = 1;
printf("%d make a product\n",pthread_self());
showProductArray();
sem_post(&mutex);
sem_post(&full);
// 减慢程序运行速度以便观察
sleep(1);
}
}
void* consume(void* args) {
while(1) {
sem_wait(&full);
sem_wait(&mutex);
product[(c_count++)%5] = 0;
printf("a product was taken\n");
showProductArray();
sem_post(&mutex);
sem_post(&empty);
// 减慢程序运行速度以便观察
sleep(1);
}
}
int main() {
sem_init(&full,0,0); sem_init(&empty,0,5); sem_init(&mutex,0,1);
pthread_t producers[3];
for (int i=0; i<3; i++) {
pthread_create(&producers[i],NULL,produce,NULL);
}
pthread_t consumer;
pthread_create(&consumer,NULL,consume,NULL);
// 保持主线程运行
while(1) {
sleep(1);
}
sem_destroy(&full); sem_destroy(&empty); sem_destroy(&mutex);
return 0;
}