Http://wenku.baidu.com/view/b602a1beb9d528ea81c77986.html?re=view
#include <stdio.h>#include<malloc.h>#include<pthread.h>#include<semaphore.h>#defineBuffer_size 30#defineOver (-1)structproduct{intTid; intdata;};structproducers{//define producer condition variable structure structProduct Buffer[buffer_size];//buffersSem_t Sem_read;//Read Signal VolumeSem_t Sem_write;//Write Signal Volumepthread_mutex_t Wlock;//Buffer Write lockpthread_mutex_t Rlock;//Buffer read Lockpthread_mutex_tLock;//Thread_count Read-write lock intReadpos, Writepos;//Read and write locations};structproducers Buffer;intThread_count = -;//surviving producer Count//The thread ID used to identify threads internallyintids[ -] = {1,2,3,4,5,6,7,8,9,Ten, One, A, -, -, the, -, -, -, +, -, +, A, at, -, -, -, -, -, in, -};intCount =0;//count the number of consumer productsintPcount =0;//count the number of products producedvoidinit () {//initializing associated locks and variables and semaphoresBuffer.readpos =0; Buffer.writepos=0; //write semaphore is 1 smaller than buffer, preventing buffer full and buffer space from being confusedSem_init (&buffer.sem_write,0, buffer_size-1); Sem_init (&buffer.sem_read,0,0); Pthread_mutex_init (&Buffer.wlock, NULL); Pthread_mutex_init (&Buffer.rlock, NULL); Pthread_mutex_init (&buffer.Lock, NULL);}voidPutintTidintdata) { //put a data in the bufferSem_wait (&buffer.sem_write); //lock before production and prevent other threads from producing at the same timePthread_mutex_lock (&Buffer.wlock); Buffer.buffer[buffer.writepos].tid=Tid; Buffer.buffer[buffer.writepos].data=data; Buffer.writepos++; ++Pcount; if(Buffer.writepos >=buffer_size) Buffer.writepos=0; Pthread_mutex_unlock (&Buffer.wlock); Sem_post (&buffer.sem_read);}//read the data and removestructProduct *Get(inttid) { structProduct * produce =NULL; //lock before consumption to prevent other threads from consuming at the same timePthread_mutex_lock (&Buffer.rlock); //If the producer thread is not fully exited, or there is still a product in the buffer, you can try to get the product if(Thread_count >0|| Buffer.readpos! =buffer.writepos) {//subtract a "1" from the semaphore value, but it will always wait for the semaphore to be a non-0 value before starting to subtractSem_wait (&buffer.sem_read); intpos =Buffer.readpos; //iterate over existing products to find the right product while(POS! =buffer.writepos) {intID =Buffer.buffer[pos].tid; if(Id >Ten&& ID <= -&& tid = =ID) {//If the product is the producer thread number 10<id<=20 then it can be consumed by the same consumer thread as its thread numberproduce = (structProduct *) malloc (sizeof(structProduct)); Produce->tid =ID; Produce->data =Buffer.buffer[pos].data; Break; } Else if(ID <=Ten&& (id%2= = tid%2)) { //If the product is the producer thread number <=10 can be used for the same consumer consumption as its line Cheng parityproduce = (structProduct *) malloc (sizeof(structProduct)); Produce->tid =ID; Produce->data =Buffer.buffer[pos].data; Break; } Else if(Id > -) { //If the product is the producer thread number >20 can be consumed by any consumerproduce = (structProduct *) malloc (sizeof(structProduct)); Produce->tid =ID; Produce->data =Buffer.buffer[pos].data; Break; } POS= (pos+1)%buffer_size; } if(produce) {//If a product is obtained, the consumption count is +1, and the element in the head of the team is overwritten to the removed position++count; Buffer.buffer[pos].tid=Buffer.buffer[buffer.readpos].tid; Buffer.buffer[pos].data=Buffer.buffer[buffer.readpos].data; ++Buffer.readpos; } if(Buffer.readpos >=buffer_size) Buffer.readpos=0; //releasing a buffer-writable semaphore if the product is obtained, or releasing a readable semaphore if(produce) Sem_post (&buffer.sem_write); ElseSem_post (&buffer.sem_read); Pthread_mutex_unlock (&Buffer.rlock); }ElsePthread_mutex_unlock (&Buffer.rlock); returnProduce;}void*producer (void*data) { //30 products per thread cycle intTID = * ((int*) data); intN; for(n =1; N <= -; n++) {printf ("producer%d product%d \ n", Tid, n); Put (TID, n); } //Thread_count minus 1 after each exit of a producer threadPthread_mutex_lock (&buffer.Lock); --Thread_count; Pthread_mutex_unlock (&buffer.Lock); returnNULL;}void*consumer (void*data) { intTID = * ((int*) data); structProduct *d =NULL; while(1) {D=Get(TID); if(d) {printf ("consumer%d Consum%d from Producer%d \ n", Tid, d->data,d->tid); Free (d); } pthread_mutex_lock (&buffer.Lock); //when all producer threads have exited and there are no products in the buffer that the thread can consume, exit the thread if(d = = NULL && Thread_count = =0) {Pthread_mutex_unlock (&buffer.Lock); Break; }ElsePthread_mutex_unlock (&buffer.Lock); } returnNULL;}intMainvoid) {pthread_t th_a[ -], th_b[ -]; void*retval; Init (&buffer); inti; for(i =0; i< -; ++i) {//create producers and consumersPthread_create (&th_a[i], NULL, producer, &Ids[i]); Pthread_create (&th_b[i], NULL, Consumer, &Ids[i]); } for(i =0; i< -; ++i) {//to join a thread to the main thread groupPthread_join (Th_a[i], &retval); Pthread_join (Th_b[i],&retval); } printf ("Product%d products\n", Pcount); printf ("consume%d products\n", Count); return 0;}
Producer Consumer Issues