11#include <stdio.h>
22#include <stdlib.h>
3- #include <string .h>
3+ #include <unistd .h>
44#include <pthread.h>
5+ #include <time.h>
56
6- #define NUM_THREADS 10
7+ #define NUM_READERS 5
8+ #define NUM_READS 5
9+ #define NUM_WRITERS 5
10+ #define NUM_WRITES 5
711
8- //
9- // Created by Emmanuel Massaquoi on 6/19/17.
10- //
12+ unsigned int gSharedValue = 0 ;
13+ int gWaitingReaders = 0 ;
14+ int gReaders = 0 ;
1115
12- int shared_var = 0 ;
13- int resource_use ;
14- int num_reader = 0 ;
1516
16- int reading = 0 ;
17- int writing = 1 ;
17+ pthread_mutex_t gSharedMemoryLock = PTHREAD_MUTEX_INITIALIZER ;
18+ pthread_cond_t gReadPhase = PTHREAD_COND_INITIALIZER ;
19+ pthread_cond_t gWritePhase = PTHREAD_COND_INITIALIZER ;
1820
19- pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER ;
20- pthread_cond_t read_phase = PTHREAD_COND_INITIALIZER ;
21- pthread_cond_t write_phase = PTHREAD_COND_INITIALIZER ;
21+ void * reader ( void * param ) ;
22+ void * writer ( void * param ) ;
23+ int usleep ( __useconds_t sec ) ;
2224
23- void * reader (void * param );
24- void * writer (void * param );
25+ //void waitFor(unsigned int secs);
2526
2627
2728int main (int argc , char * argv []) {
2829
29- pthread_t tid [NUM_THREADS ];
30+ int readerNum [NUM_READERS ];
31+ int writerNum [NUM_WRITERS ];
3032
31- for (int i = 0 ; i < 5 ; i ++ ) {
33+ pthread_t readerThreadIDs [NUM_READERS ];
34+ pthread_t writerThreadIDs [NUM_WRITERS ];
3235
33- printf ("Create Reader\n" );
34- if (pthread_create (& tid [i ], NULL , reader , NULL ) != 0 ) {
36+ srandom ((unsigned int )time (NULL ));
37+
38+
39+ for (int i = 0 ; i < NUM_READERS ; i ++ ) {
40+ readerNum [i ] = i ;
41+
42+ if (pthread_create (& readerThreadIDs [i ], NULL , reader , & readerNum [i ]) != 0 ) {
3543 fprintf (stderr , "Unable to create reader thread" );
3644 exit (1 );
3745 }
46+ }
47+
48+ for (int i = 0 ; i < NUM_WRITERS ; i ++ ) {
49+ writerNum [i ] = i ;
3850
39- printf ("Create Writer\n" );
40- if (pthread_create (& tid [i + 5 ], NULL , writer , NULL ) != 0 ) {
51+ if (pthread_create (& writerThreadIDs [i ], NULL , writer , & writerNum [i ]) != 0 ) {
4152 fprintf (stderr , "Unable to create writer thread" );
4253 exit (1 );
4354 }
4455 }
4556
46- for (int j = 0 ; j < NUM_THREADS ; ++ j ) {
47- pthread_join (tid [j ], NULL );
57+
58+ for (int i = 0 ; i < NUM_READERS ; i ++ ) {
59+ pthread_join (readerThreadIDs [i ], NULL );
4860 }
4961
50- printf ("Parent quiting\n" );
62+ for (int i = 0 ; i < NUM_WRITERS ; i ++ ) {
63+ pthread_join (writerThreadIDs [i ], NULL );
64+ }
5165
5266 return 0 ;
5367}
5468
5569void * reader (void * param ) {
5670
57- for (int i = 1 ; i <=20 ; i ++ ) {
71+ int id = * ((int * )param );
72+ int numReaders = 0 ;
73+
74+ for (int i = 0 ; i < NUM_READS ; i ++ ) {
75+
76+ usleep (1000 * (random () % NUM_READERS + NUM_WRITERS ));
5877
59- pthread_mutex_lock (& m );
78+ pthread_mutex_lock (& gSharedMemoryLock );
6079
61- while (resource_use == writing ) {
62- pthread_cond_wait (& read_phase , & m );
80+ gWaitingReaders ++ ;
81+ while (gReaders == -1 ) {
82+ pthread_cond_wait (& gReadPhase , & gSharedMemoryLock );
6383 }
84+ gWaitingReaders -- ;
85+ numReaders = ++ gReaders ;
6486
65- printf ("Reader Value: %d\n" , shared_var );
66- printf ("Number of Readers Present: %d\n" , num_reader );
87+ pthread_mutex_unlock (& gSharedMemoryLock );
6788
68- resource_use = reading ;
69- pthread_cond_broadcast (& write_phase );
89+ fprintf (stdout , "[r%d] reading %u [readers: %2d]\n" , id , gSharedValue , numReaders );
7090
71- pthread_mutex_unlock (& m );
91+ pthread_mutex_lock (& gSharedMemoryLock );
92+ gReaders -- ;
93+ if (gReaders == 0 ) {
94+ pthread_cond_signal (& gWritePhase );
95+ }
96+ pthread_mutex_unlock (& gSharedMemoryLock );
7297 }
7398
74- return 0 ;
99+ pthread_exit ( 0 ) ;
75100}
76101
77102void * writer (void * param ) {
78103
79- for (int i = 1 ; i <= 20 ; ++ i ) {
80- pthread_mutex_lock (& m );
81-
82- while (resource_use == reading || num_reader != 0 ) {
83- pthread_cond_wait (& write_phase , & m );
84- }
104+ int id = * ((int * )param );
105+ int numReaders = 0 ;
85106
86- shared_var = i ;
87- printf ("Written Value: %d\n" , shared_var );
88- printf ("Number of Readers Present: %d\n" , num_reader );
107+ for (int i = 0 ; i < NUM_WRITES ; ++ i ) {
89108
90- resource_use = writing ;
91- pthread_cond_broadcast (& read_phase );
109+ usleep (1000 * (random () % NUM_READERS + NUM_WRITERS ));
92110
93- pthread_mutex_unlock (& m );
111+ pthread_mutex_lock (& gSharedMemoryLock );
112+ while (gReaders != 0 ) {
113+ pthread_cond_wait (& gWritePhase , & gSharedMemoryLock );
114+ }
115+ gReaders = -1 ;
116+ numReaders = gReaders ;
117+ pthread_mutex_unlock (& gSharedMemoryLock );
118+
119+ fprintf (stdout , "[w%d] writing %u* [readers: %2d]\n" , id , ++ gSharedValue , numReaders );
120+
121+ pthread_mutex_lock (& gSharedMemoryLock );
122+ gReaders = 0 ;
123+ if (gWaitingReaders > 0 ) {
124+ pthread_cond_broadcast (& gReadPhase );
125+ } else {
126+ pthread_cond_signal (& gWritePhase );
127+ }
128+ pthread_mutex_unlock (& gSharedMemoryLock );
94129 }
95130
96- }
131+ pthread_exit (0 );
132+ }
133+
134+ /*void waitFor (unsigned int secs) {
135+ unsigned int retTime = time(0) + secs;
136+ while(time(0) < retTime);
137+ }*/
0 commit comments