pc1.c: 使用條件變量解決生產者、計算者、消費者問題
/*
? 系統中有3個線程:生產者、計算者、消費者
? 系統中有2個容量為4的緩沖區:buffer1、buffer2
? 生產者生產'a'、'b'、'c'、‘d'、'e'、'f'、'g'、'h'八個字符,放入到buffer1
? 計算者從buffer1取出字符,將小寫字符轉換為大寫字符,放入到buffer2
? 消費者從buffer2取出字符,將其打印到屏幕上
實現思路:設置兩個大小為4的緩沖區,第一個為生產者和計算著共享,第二個為計算者和消費者共享。
1、生產者線程產生字符,將字符寫入緩沖區buffer1中,并將指針后移,當緩沖區被寫滿是,將生產者線程掛起,喚醒計算者線程,等待緩沖區buffer1有空閑存儲空間的時候再喚醒生產者線程。
2、計算者線程從buffer1中讀取數據,并移動指針,并將讀取的數據寫入buffer2中,當buffer1有空閑時,喚醒生產者進程,當buffer2被寫滿時喚醒消費者進程。
3、消費者進程從buffer2中讀取字符并輸出,并移動指針,當buffer2有空閑的時候,喚醒計算者進程。
實現代碼:
#include<stdio.h>
#include<pthread.h>
#include<unistd.h>#define CAPACITY 4char buffer1[4];
char buffer2[4];int crea; //生產者
int comp1;//計算者
int comp2;//計算者
int cons; //消費者 int buffer1_is_empty(){return crea==comp1;
}int buffer1_is_full(){return (crea+1)%CAPACITY==comp1;
}int buffer2_is_empty(){return comp2==cons;
}int buffer2_is_full(){return (cons+1)%CAPACITY==comp2;
}int get_item1(){int item;item=buffer1[comp1];comp1=(comp1+1)%CAPACITY;return item;
}int get_item2(){int item;item=buffer2[cons];cons=(cons+1)%CAPACITY;return item;
}int put_item1(int item){buffer1[crea]=item;crea=(crea+1)%CAPACITY;
}int put_item2(int item){buffer2[comp2]=item;comp2=(comp2+1)%CAPACITY;
}pthread_mutex_t mutex1;
pthread_cond_t wait_empty_buffer1;
pthread_cond_t wait_full_buffer1;pthread_mutex_t mutex2;
pthread_cond_t wait_empty_buffer2;
pthread_cond_t wait_full_buffer2;#define ITEM_COUNT (CAPACITY *2)void *consumer(void *arg){int i;int item;for(i=0;i<ITEM_COUNT;i++){pthread_mutex_lock(&mutex2);while(buffer2_is_empty())pthread_cond_wait(&wait_full_buffer2,&mutex2);item=get_item2();printf(" consume item:%c\n",item);pthread_cond_signal(&wait_empty_buffer2);pthread_mutex_unlock(&mutex2);}return NULL;
}void *computer(void *arg){int i;int item;for(i=0;i<ITEM_COUNT;i++){pthread_mutex_lock(&mutex1);while(buffer1_is_empty())pthread_cond_wait(&wait_full_buffer1,&mutex1);item=get_item1();printf(" computer get item:%c\n",item);item-=32;pthread_cond_signal(&wait_empty_buffer1);pthread_mutex_unlock(&mutex1);pthread_mutex_lock(&mutex2);while(buffer2_is_full())pthread_cond_wait(&wait_empty_buffer2,&mutex2);put_item2(item);printf(" computer put item:%c\n",item);pthread_cond_signal(&wait_full_buffer2);pthread_mutex_unlock(&mutex2);}return NULL;
}void *create(void *arg){int i;int item;for(i=0;i<ITEM_COUNT;i++){pthread_mutex_lock(&mutex1);while(buffer1_is_full())pthread_cond_wait(&wait_empty_buffer1,&mutex1);item='a'+i;put_item1(item);printf("create item:%c\n",item);pthread_cond_signal(&wait_full_buffer1);pthread_mutex_unlock(&mutex1);}return NULL;
}int main(){pthread_t consumer_tid;pthread_t computer_tid;pthread_mutex_init(&mutex1,NULL);pthread_mutex_init(&mutex2,NULL);pthread_cond_init(&wait_empty_buffer1,NULL);pthread_cond_init(&wait_full_buffer1,NULL);pthread_cond_init(&wait_empty_buffer2,NULL);pthread_cond_init(&wait_full_buffer2,NULL);pthread_create(&consumer_tid,NULL,consumer,NULL);pthread_create(&computer_tid,NULL,computer,NULL);create(NULL);pthread_join(consumer_tid,NULL);pthread_join(computer_tid,NULL);pthread_mutex_destroy(&mutex1);pthread_mutex_destroy(&mutex2);return 0;
}
歡迎留言交流。。。