Look back at the producer consumer model.
#include <stdio.h>#include<stdlib.h>#include<string.h>#include<semaphore.h>#include<unistd.h>#include<sys/types.h>#include<pthread.h>#defineErr_exit (M) Do{perror (M); Exit (Exit_failure); } while(0)#defineConsumers_count 1#defineProducers_count 2#defineBuffsize 10intg_buffer[buffsize];unsigned Short inch=0; unsigned Short out=0; unsigned Shortproduct_id =0; unsigned Shortconsume_id =0; sem_t g_sen_full;sem_t g_sen_empty;pthread_mutex_t g_mutex;pthread_t g_thread[consumers_count+Producers_count];void* Consume (void*Arg) { inti; while(1) {sem_wait (&g_sen_empty); Pthread_mutex_lock (&G_mutex); for(i =0; i < buffsize; ++i) {/*Code*/printf ("%02d\n", i); if(G_buffer[i] = =-1) printf ("%s","NULL"); Elseprintf ("%d\n", G_buffer[i]); if(i = = out) printf ("\t<--consume\n"); printf ("\ n"); } consume_id= g_buffer[ out]; printf ("begin consume Product%d\n", consume_id); g_buffer[ out] = -1; out= ( out+1) %buffsize; Pthread_mutex_unlock (&G_mutex); Sem_post (&g_sen_full); Sleep (1); } returnNULL;}void* Produce (void*Arg) { intnum = (int) Arg; inti; while(1) {printf ("%d waiting buffer_full\n", num); Sem_wait (&g_sen_full); Pthread_mutex_lock (&G_mutex); for(i =0; i < buffsize; ++i) {/*Code*/printf ("%02d\n", i); if(G_buffer[i] = =-1) printf ("%s","NULL"); Elseprintf ("%d\n", G_buffer[i]); if(i = =inch) printf ("\t<--produce\n"); printf ("\ n"); } printf ("begin produce Product%d\n", product_id); g_buffer[inch] =product_id; inch= (inch+1) %buffsize; printf ("End Produce Product%d\n", product_id++); Pthread_mutex_unlock (&G_mutex); Sem_post (&g_sen_empty); } returnNULL;}intMainintargcConst Char*argv[]) { inti; for(i =0; i < buffsize; ++i) {/*Code*/G_buffer[i]= -1; } //Initialize the semaphoreSem_init (&g_sen_full,0, buffsize); Sem_init (&g_sen_empty,0,0); //Initialize lockPthread_mutex_init (&G_mutex, NULL); for(i =0; i < Consumers_count; ++i) {/*Code*/Pthread_create (&g_thread[i], NULL, consume, (void*) (i); } for(i =0; i < Producers_count; ++i) {/*Code*/Pthread_create (&g_thread[consumers_count+i], NULL, Produce, (void*) (i); } for(i =0; i < Consumers_count+producers_count; ++i) {/*Code*/Pthread_join (G_thread[i], NULL); } Sem_destroy (&g_sen_empty); Sem_destroy (&g_sen_full); Pthread_mutex_destroy (&G_mutex); return 0;}
Dongguan Orient
Write a version of the conditional variable again.
#include <stdio.h>#include<stdlib.h>#include<string.h>#include<semaphore.h>#include<unistd.h>#include<sys/types.h>#include<pthread.h>#defineErr_exit (M) Do{perror (M); Exit (Exit_failure); } while(0)#defineConsumers_count 2#defineProducers_count 1#defineBuffsize 10unsigned Short inch=0; unsigned Short out=0; unsigned Shortproduct_id =0; unsigned Shortconsume_id =0; sem_t g_sen_full;sem_t g_sen_empty;pthread_mutex_t g_mutex;pthread_cond_t g_cond;pthread_t g_thread[CONSUMERS_ COUNT+Producers_count];intNready =0;void* Consume (void*Arg) { intnum = (int) Arg; while(1) {Pthread_mutex_lock (&G_mutex); while(nready==0) {printf ("begin wait a condtion\n"); Pthread_cond_wait (&g_cond, &G_mutex); } printf ("no.%dend of Wait a condtion ... \ n", num); --Nready; printf ("consumer%d consumes a product \ n", num); Pthread_mutex_unlock (&G_mutex); } returnNULL;}void* Produce (void*Arg) { intnum = (int) Arg; while(1) {Pthread_mutex_lock (&G_mutex); ++Nready; printf ("producer%d produced a product and sent signal. \ n", num); Pthread_cond_signal (&G_cond); Pthread_mutex_unlock (&G_mutex); Sleep (5); } returnNULL;}intMainintargcConst Char*argv[]) { inti; Pthread_mutex_init (&G_mutex, NULL); Pthread_cond_init (&G_cond, NULL); for(i =0; i < Consumers_count; ++i) {/*Code*/Pthread_create (&g_thread[i], NULL, Produce, (void*) (i); } for(i =0; i < Producers_count; ++i) {/*Code*/Pthread_create (&g_thread[i+consumers_count], NULL, consume, (void*) (i); } for(i =0; i < Consumers_count+producers_count; ++i) {/*Code*/Pthread_join (G_thread[i], NULL); } Pthread_mutex_destroy (&G_mutex); Pthread_cond_destroy (&G_cond); return 0;}
Pthread_cond_wait the primitive language of this function:
One. Unlock G_mutex to allow other threads to enter the critical section
Two. Wait for the condition until the thread can wake it up and then let the CPU
Three. When awakened, it re-locks the G_mutex
For producers & consumers to judge why use while instead of if, we've discussed it before
If the value is judged once, and re-locking does not guarantee that it is still satisfied.
Linux Learning: Review of producer & Consumer models