==============================================================
Experiment 11: Readers-Writers Problem Using Semaphores
==============================================================
[Back to Index]
--------------------------------------------------------------
THEORY:
A shared resource (database, file, variable) is accessed by
two types of processes:
Readers:
- Only read the data
- Do not modify it
- Many readers can read simultaneously
Writers:
- Modify the data
- Must have exclusive access
- No other reader or writer can access the resource
while a writer is writing
The main goal is to ensure correctness and consistency
of shared data.
--------------------------------------------------------------
CONSTRAINTS:
- Multiple readers can read at the same time.
- Only one writer can write at a time.
- No reader should read while writer is writing.
- No two writers should write at the same time.
==============================================================
PART 1: Reader Priority
==============================================================
READER ALGORITHM (Reader Priority):
wait(mutex)
read_count++
if read_count == 1:
wait(rw_mutex) // first reader locks writers out
signal(mutex)
READ DATA
wait(mutex)
read_count--
if read_count == 0:
signal(rw_mutex) // last reader unlocks resource
signal(mutex)
WRITER ALGORITHM (Reader Priority):
wait(rw_mutex) // Only one writer at a time
WRITE DATA
signal(rw_mutex)
--------------------------------------------------------------
SOURCE CODE: reader_writer_reader_priority.c
--------------------------------------------------------------
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>
sem_t rw_mutex; // Controls access to shared resource
sem_t mutex; // Controls read_count access
int read_count = 0;
void *reader(void *arg) {
int id = *(int *)arg;
sem_wait(&mutex);
read_count++;
if (read_count == 1)
sem_wait(&rw_mutex); // First reader blocks writers
sem_post(&mutex);
// Critical Section
printf("Reader %d is READING\n", id);
sleep(1);
printf("Reader %d is DONE reading\n", id);
sem_wait(&mutex);
read_count--;
if (read_count == 0)
sem_post(&rw_mutex); // Last reader releases writers
sem_post(&mutex);
return NULL;
}
void *writer(void *arg) {
int id = *(int *)arg;
sem_wait(&rw_mutex); // Writer needs exclusive access
// Critical Section
printf("\tWriter %d is WRITING\n", id);
sleep(2);
printf("\tWriter %d is DONE writing\n", id);
sem_post(&rw_mutex);
return NULL;
}
int main() {
pthread_t r[5], w[5];
int ids[5];
sem_init(&rw_mutex, 0, 1);
sem_init(&mutex, 0, 1);
for (int i = 0; i < 5; i++)
ids[i] = i + 1;
for (int i = 0; i < 5; i++) {
pthread_create(&r[i], NULL, reader, &ids[i]);
pthread_create(&w[i], NULL, writer, &ids[i]);
}
for (int i = 0; i < 5; i++) {
pthread_join(r[i], NULL);
pthread_join(w[i], NULL);
}
sem_destroy(&rw_mutex);
sem_destroy(&mutex);
return 0;
}
--------------------------------------------------------------
COMPILE: gcc -o rw_reader reader_writer_reader_priority.c -lpthread
==============================================================
PART 2: Writer Priority
==============================================================
READER ALGORITHM (Writer Priority):
Wait on queue
Wait on mutex
Increment read_count
If read_count == 1, wait on rw_mutex
Signal mutex
Signal queue
Read the shared data
Wait on mutex
Decrement read_count
If read_count == 0, signal rw_mutex
Signal mutex
WRITER ALGORITHM (Writer Priority):
Wait on queue
Wait on rw_mutex
Write to the shared data
Signal rw_mutex
Signal queue
--------------------------------------------------------------
SOURCE CODE: reader_writer_writer_priority.c
--------------------------------------------------------------
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>
sem_t mutex; // Protects read_count
sem_t rw_mutex; // Exclusive access to shared resource
sem_t queue; // Enforces writer priority
int read_count = 0;
void *reader(void *arg) {
int id = *(int *)arg;
sem_wait(&queue); // Block if writer waiting
sem_wait(&mutex);
read_count++;
if (read_count == 1)
sem_wait(&rw_mutex); // First reader blocks writers
sem_post(&mutex);
sem_post(&queue); // Allow others to queue
// Critical Section (Reading)
printf("Reader %d is READING\n", id);
sleep(1);
printf("Reader %d has FINISHED READING\n", id);
sem_wait(&mutex);
read_count--;
if (read_count == 0)
sem_post(&rw_mutex); // Last reader releases writer
sem_post(&mutex);
return NULL;
}
void *writer(void *arg) {
int id = *(int *)arg;
sem_wait(&queue); // Writer gets priority
sem_wait(&rw_mutex); // Exclusive access
// Critical Section (Writing)
printf("\tWriter %d is WRITING\n", id);
sleep(2);
printf("\tWriter %d has FINISHED WRITING\n", id);
sem_post(&rw_mutex);
sem_post(&queue);
return NULL;
}
int main() {
pthread_t readers[5], writers[5];
int id[5];
sem_init(&mutex, 0, 1);
sem_init(&rw_mutex, 0, 1);
sem_init(&queue, 0, 1);
for (int i = 0; i < 5; i++) {
id[i] = i + 1;
pthread_create(&readers[i], NULL, reader, &id[i]);
pthread_create(&writers[i], NULL, writer, &id[i]);
}
for (int i = 0; i < 5; i++) {
pthread_join(readers[i], NULL);
pthread_join(writers[i], NULL);
}
sem_destroy(&mutex);
sem_destroy(&rw_mutex);
sem_destroy(&queue);
return 0;
}
--------------------------------------------------------------
COMPILE: gcc -o rw_writer reader_writer_writer_priority.c -lpthread
==============================================================
[Prev: Exp 10] | [Next: Exp 12]
==============================================================