#include #include #include #include #include int shared_data = 0; int reader_count = 0; int waiting_reader_count = 0; int writer_count = 0; pthread_mutex_t mutex_lock; pthread_cond_t readers_cond; pthread_cond_t writers_cond; void *reader(void *not_used) { while (1) { // ACQUIRE pthread_mutex_lock(&mutex_lock); waiting_reader_count++; while (writer_count > 0) { pthread_cond_wait(&readers_cond, &mutex_lock); } waiting_reader_count--; reader_count++; assert(writer_count == 0); pthread_mutex_unlock(&mutex_lock); // USE (DO_TASK) usleep(100000); printf("I read\n"); // RELEASE pthread_mutex_lock(&mutex_lock); reader_count--; assert(writer_count == 0); if (reader_count == 0) { pthread_cond_signal(&writers_cond); } pthread_mutex_unlock(&mutex_lock); usleep(1000000); } return NULL; } void *writer(void *not_used) { while (1) { // ACQUIRE pthread_mutex_lock(&mutex_lock); while (reader_count > 0 || waiting_reader_count > 0 || writer_count > 0) { pthread_cond_wait(&writers_cond, &mutex_lock); } assert(reader_count == 0 && waiting_reader_count == 0 && writer_count == 0); writer_count++; pthread_mutex_unlock(&mutex_lock); // USE (DO_TASK) shared_data++; usleep(200000); printf("I wrote\n"); // RELEASE pthread_mutex_lock(&mutex_lock); writer_count--; assert(reader_count == 0 && writer_count == 0); if (waiting_reader_count > 0) { pthread_cond_broadcast(&readers_cond); } else { pthread_cond_signal(&writers_cond); } pthread_mutex_unlock(&mutex_lock); usleep(100000); } return NULL; } #define NUM_READERS 5 #define NUM_WRITERS 2 int main() { pthread_t readers[NUM_READERS]; pthread_t writers[NUM_WRITERS]; int reader_ids[NUM_READERS]; int writer_ids[NUM_WRITERS]; pthread_mutex_init(&mutex_lock, NULL); pthread_cond_init(&readers_cond, NULL); pthread_cond_init(&writers_cond, NULL); for (int i = 0; i < NUM_READERS; i++) { reader_ids[i] = i + 1; if (pthread_create(&readers[i], NULL, reader, &reader_ids[i]) != 0) { return 1; } } for (int i = 0; i < NUM_WRITERS; i++) { writer_ids[i] = i + 1; if (pthread_create(&writers[i], NULL, writer, &writer_ids[i]) != 0) { return 1; } } for (int i = 0; i < NUM_READERS; i++) { pthread_join(readers[i], NULL); } for (int i = 0; i < NUM_WRITERS; i++) { pthread_join(writers[i], NULL); } pthread_mutex_destroy(&mutex_lock); pthread_cond_destroy(&readers_cond); pthread_cond_destroy(&writers_cond); return 0; }