【Linux】基於環形buf的多消費者多生產者問題
阿新 • • 發佈:2019-01-22
生產者消費者問題,是一個多執行緒同步問題的經典案例。該問題描述了兩個共享固定大小緩衝區的執行緒——即所謂的“生產者”和“消費者”——在實際執行時會發生的問題。生產者的主要作用是生成一定量的資料放到緩衝區中,然後重複此過程。與此同時,消費者也在緩衝區消耗這些資料。該問題的關鍵就是要保證生產者不會在緩衝區滿時加入資料,消費者也不會在緩衝區中空時消耗資料。
下面是該問題的環形模型
當生產者在生產時,消費者不能進行消費,當消費者在消費時生產者不能進行生產,這些都說的是在同一資料操作區進行操作
以上圖為例,即消費者永遠不能追上生產者,生產者永遠不能追上消費者,更別說超過一圈了
下面是用程式碼實現
#include<stdio.h> #include<stdlib.h> #include<errno.h> #include<pthread.h> #include<semaphore.h> #define _SIZE_ 64 sem_t blanks; sem_t datas; int buf[_SIZE_]={ 0 }; //pthread_lock_t mylock; void *product(void * arg) { int i=1; while(1){ for(i=0;i<=_SIZE_;i++) { sleep(1); if(buf[i]==0) { sem_wait(&blanks); int _product=rand()%123; buf[i]=i; printf("product is:%d,data is :%d\n",_product,i); sem_post(&datas); } } } } void *consumer() { int i=1; while(1){ sem_wait(&datas); for(;i<=_SIZE_;i++) { sleep(1); if(buf[i]!=0) { int _consumer=rand()%1242; printf("consumer :%d,data is:%d\n",_consumer,i); buf[i]=0; } } sem_post(&blanks); } } void run() { sem_init(&blanks,0,_SIZE_); sem_init(&datas,0,0); pthread_t _consumer; pthread_t _product; pthread_create(&_consumer,NULL,consumer,NULL); pthread_create(&_product,NULL,product,NULL); pthread_join(_consumer,NULL); pthread_join(_product,NULL); sem_destroy(&blanks); sem_destroy(&datas); } int main() { run(); return 0; }
執行結果
可以看出有多個消費者在消費,多個生產者在生產,並且消費者總是在生產者後面消費