多個生產者與消費者


  生產者消費者問題屬於有界緩沖區問題。我們現在講述多個生產者向一個緩沖區中存入數據,多個生產者從緩沖區中取數據。共享緩沖區作為一個環繞緩沖區,存數據到頭時再從頭開始。我們使用一個互斥量保護生產者向緩沖區中存入數據。由於有多個生產者,因此需要記住現在向緩沖區中存入的位置。使用一個互斥量保護緩沖區中消息的數目,這個生產的數據數目作為生產者和消費者溝通的橋梁。使用一個條件變量用於喚醒消費者。由於有多個消費者,同樣消費者也需要記住每次取的位置。

#include "unpipc.h"
#include "my_err.h"
#include <pthread.h>
#define MAXITEMS 6
#define MAXTHREADS 3

int buffer[MAXITEMS];

//生產者使用的結構體
struct shared { pthread_mutex_t mutex; int input;//下標 int i;//存入的值 }shared={PTHREAD_MUTEX_INITIALIZER};
//消費者使用的結構體,生產者也會使用
struct ready { pthread_mutex_t mutex; pthread_cond_t cond; int nready;//生產者為消費者准備好的可用的商品數量 int nget;//消費者從倉庫中抓取商品的次數 }ready={PTHREAD_MUTEX_INITIALIZER,PTHREAD_COND_INITIALIZER}; void *produce(void *arg) { while(1) { pthread_mutex_lock(&shared.mutex); if(shared.i>=MAXITEMS)//倉庫滿,不能再生產 { pthread_mutex_unlock(&shared.mutex); return NULL; } buffer[shared.input]=shared.i; if(++shared.input>=MAXITEMS)//1...MAXITEMS,循環緩沖,如果抓取的次數大於MAXITEMS,從頭在開始計數 shared.input=0; //++shared.input; ++shared.i;// pthread_mutex_unlock(&shared.mutex); //使臨界區盡量短使用多個互斥量,生產完畢可以消費了 pthread_mutex_lock(&ready.mutex); if(ready.nready==0)//如果有消費者等待消費,則喚醒 pthread_cond_signal(&ready.cond); ++ready.nready;//可以消費的商品的數目+1 pthread_mutex_unlock(&ready.mutex); } return NULL; } void *consume(void *arg) { while(1) { pthread_mutex_lock(&ready.mutex); if(ready.nready==0)//如果可以消費的數目==0,倉庫中沒有可消費的商品,等待 pthread_cond_wait(&ready.cond,&ready.mutex); if(++ready.nget>=MAXITEMS)//1...MAXITEMS { if(ready.nget==MAXITEMS)//抓取商品的次數==倉庫的最大容量時少操作一次, printf("buffer[%d] = %d \n",ready.nget-1,buffer[(ready.nget-1)%MAXITEMS]); pthread_cond_signal(&ready.cond);// pthread_mutex_unlock(&ready.mutex); return NULL; } --ready.nready; pthread_mutex_unlock(&ready.mutex); printf("buffer[%d] = %d\n",ready.nget-1,buffer[(ready.nget-1)%MAXITEMS]); } return NULL; } int main() { pthread_setconcurrency(MAXTHREADS*2);// int i; pthread_t pid_produce[MAXTHREADS],pid_consume[MAXTHREADS]; for(i=0;i<MAXTHREADS;++i) pthread_create(&pid_produce[i],NULL,produce,NULL); for(i=0;i<MAXTHREADS;++i) pthread_create(&pid_consume[i],NULL,consume,NULL); for(i=0;i<MAXTHREADS;++i) pthread_join(pid_produce[i],NULL); for(i=0;i<MAXTHREADS;++i) pthread_join(pid_consume[i],NULL); exit(0); }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM