#include <stdio.h>#include<stdlib.h>#include<unistd.h>#include<pthread.h>#defineBuffer_size 21//Initialize the size of the storage space#defineEnd_flag (-1)//used to exit a loopstructproducts{intBuffer[buffer_size];//Storage SpacePthread_mutex_t Locker;//declaring a mutex variablepthread_cond_t Notempty;//declaring condition Variablespthread_cond_t notfull;intPosreadfrom;intPoswriteto;};intflag1=0, flag2=0, num1=0, num2=0;//variables must be remembered initialized, very important, the first two in order to mark, the latter two in order to countstructProducts and products;//define struct variables, which are used belowintBufferisfull (structproducts* products)//if full, 1 is returned, otherwise 0 is returned;{if((Products->poswriteto +1)%buffer_size==products->Posreadfrom) {return(1);}return(0);}intBufferisempty (structproducts* products)//returns 1 if empty, otherwise returns 0;{if((products->poswriteto) = = (products->Posreadfrom)) {return(1);}return(0);}/*Manufacturing Products*/voidProduce (structproducts* Products,intItem) {/*Atomic Operation*/Pthread_mutex_lock (&products->locker);/*no space to write*/ while(Bufferisfull (Products)) {Flag1=1;//Tag VariablesPthread_cond_wait (&products->notfull, &products->locker);} /*Write Data*/ Products->buffer[products->poswriteto] =item;products->poswriteto++;p Thread_mutex_unlock (&products->locker);//send a signal after unlocking/*Sending*/ if(flag2==2) {Flag2=0;//This line of code is very important, I just forgot to write in the beginning, and then I will continue to output this sentencePthread_cond_signal (&products->notempty); printf ("produce called the wake function%d times \ n", ++NUM1);//Check that the code is performing correctly because adding this line of code makes it easier to analyze }}intConsume (structproducts*Products ) {intItem;pthread_mutex_lock (&products->locker);/*waiting for empty time, countless data readable*/ while(Bufferisempty (Products)) {Flag2=2;p thread_cond_wait (&products->notempty, &products->locker);}/*Extracting Data*/Item= products->buffer[products->Posreadfrom];p roducts->posreadfrom++;p Thread_mutex_unlock (&products->locker);if(flag1==1) {Flag1=0;p thread_cond_signal (&products->notfull); printf ("consume called the wake function%d times \ n",++num2);}returnitem;}void* Producerthread (void*data) {inti; for(i =1; I < +; ++i) {printf ("Producer:%d\n", i); Produce (&Products , i);} Produce (&Products , end_flag);returnNULL;}void* Consumerthread (void*data) {intitem; while(1) {Item= Consume (&Products ); if(End_flag = =Item) Break;p rintf ("Consumer:%d\n", item);}return(NULL);}intMainintargcChar*argv[]) {pthread_t producer;pthread_t consumer;intResult;pthread_create (&producer, NULL, &Producerthread, NULL);p thread_create (&consumer, NULL, &Consumerthread, NULL);p Thread_join (producer, (void*) &result);p Thread_join (consumer, (void*) &result);p rintf ("products.posreadfrom=%d\n", Products.posreadfrom);//number of test cyclesprintf"products.poswriteto=%d", Products.poswriteto); exit (exit_success);}//pthread_cond_signal Here I use if to judge, because if not to judge,//every time the sentence is executed, the signal is sent out, but no one receives it! (This idea is very important)/*Why this struct variable is not initialized, but its two data members, starting from 0, really let me not know why, finally I finally understand the original because this program to the struct products structure variables, The products are declared as global variables so the system is initialized automatically! This is just a long time not to see all forgotten! */
Pthread_cond_wait and Pthread_cond_signal and the use of mutex variables