1+ #include <stdio.h>
2+ #include <stdlib.h>
3+ #include <pthread.h>
4+
5+ #define BUF_SIZE 3/* Size of shared buffer */
6+
7+ int buffer [BUF_SIZE ]; /* shared buffer */
8+ int add = 0 ; /* place to add next element */
9+ int rem = 0 ; /* place to remove next element */
10+ int num = 0 ; /* number elements in buffer */
11+
12+ pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER ; /* mutex lock for buffer */
13+ pthread_cond_t c_cons = PTHREAD_COND_INITIALIZER ; /* consumer waits on this cond var */
14+ pthread_cond_t c_prod = PTHREAD_COND_INITIALIZER ; /* producer waits on this cond var */
15+
16+ void * producer (void * param );
17+ void * consumer (void * param );
18+
19+ int main (int argc , char * argv []) {
20+
21+ pthread_t tid1 , tid2 ; /* thread identifiers */
22+ int i ;
23+
24+ /* create the threads; may be any number, in general */
25+ if (pthread_create (& tid1 , NULL , producer , NULL ) != 0 ) {
26+ fprintf (stderr , "Unable to create producer thread\n" );
27+ exit (1 );
28+ }
29+
30+ if (pthread_create (& tid2 , NULL , consumer , NULL ) != 0 ) {
31+ fprintf (stderr , "Unable to create consumer thread\n" );
32+ exit (1 );
33+ }
34+
35+ /* wait for created thread to exit */
36+ pthread_join (tid1 , NULL );
37+ pthread_join (tid2 , NULL );
38+ printf ("Parent quiting\n" );
39+
40+ return 0 ;
41+ }
42+
43+ /* Produce value(s) */
44+ void * producer (void * param ) {
45+
46+ int i ;
47+ for (i = 1 ; i <=20 ; i ++ ) {
48+
49+ /* Insert into buffer */
50+ pthread_mutex_lock (& m );
51+ if (num > BUF_SIZE ) {
52+ exit (1 ); /* overflow */
53+ }
54+
55+ while (num == BUF_SIZE ) { /* block if buffer is full */
56+ pthread_cond_wait (& c_prod , & m );
57+ }
58+
59+ /* if executing here, buffer not full so add element */
60+ buffer [add ] = i ;
61+ add = (add + 1 ) % BUF_SIZE ;
62+ num ++ ;
63+ pthread_mutex_unlock (& m );
64+
65+ pthread_cond_signal (& c_cons );
66+ printf ("producer: inserted %d\n" , i );
67+ fflush (stdout );
68+ }
69+
70+ printf ("producer quiting\n" );
71+ fflush (stdout );
72+ return 0 ;
73+ }
74+
75+ /* Consume value(s); Note the consumer never terminates */
76+ void * consumer (void * param ) {
77+
78+ int i ;
79+
80+ while (1 ) {
81+
82+ pthread_mutex_lock (& m );
83+ if (num < 0 ) {
84+ exit (1 );
85+ } /* underflow */
86+
87+ while (num == 0 ) { /* block if buffer empty */
88+ pthread_cond_wait (& c_cons , & m );
89+ }
90+
91+ /* if executing here, buffer not empty so remove element */
92+ i = buffer [rem ];
93+ rem = (rem + 1 ) % BUF_SIZE ;
94+ num -- ;
95+ pthread_mutex_unlock (& m );
96+
97+ pthread_cond_signal (& c_prod );
98+ printf ("Consume value %d\n" , i ); fflush (stdout );
99+
100+ }
101+ return 0 ;
102+ }
0 commit comments