Practicals
Semester-05
OSL
Assignment 04 B

Assignment-04-B

Title

Thread synchronization and mutual exclusion using mutex. Application to demonstrate: Reader-Writer problem with reader priority.

Theory

The reader-writer problem is a classic synchronization problem where multiple threads (readers and writers) access a shared resource (e.g., a file or database). In the case of reader priority, readers have priority over writers, meaning that readers can access the resource simultaneously as long as there are no writers. Writers, on the other hand, must have exclusive access to the resource and must block readers and other writers while writing.

Code Implementation

reader_writer.c

#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>
 
#define READERS 3
#define WRITERS 2
 
pthread_mutex_t mutex;
sem_t rw_mutex;
int readers_count = 0;
int shared_resource = 0;
 
void *reader(void *arg) {
    int id = *((int *) arg);
    while (1) {
        sleep(rand() % 3);  // Simulate reading time
        pthread_mutex_lock(&mutex);
        readers_count++;
        if (readers_count == 1) {
            sem_wait(&rw_mutex);  // First reader locks the resource for writers
        }
        pthread_mutex_unlock(&mutex);
        printf("Reader %d is reading: %d\n", id, shared_resource);
        pthread_mutex_lock(&mutex);
        readers_count--;
        if (readers_count == 0) {
            sem_post(&rw_mutex);  // Last reader releases the resource for writers
        }
        pthread_mutex_unlock(&mutex);
    }
    pthread_exit(NULL);
}
 
void *writer(void *arg) {
    int id = *((int *) arg);
    while (1) {
        sleep(rand() % 3);  // Simulate writing time
        sem_wait(&rw_mutex);  // Acquire the resource for writing
        shared_resource++;
        printf("Writer %d is writing: %d\n", id, shared_resource);
        sem_post(&rw_mutex);  // Release the resource after writing
    }
    pthread_exit(NULL);
}
 
int main() {
    pthread_t reader_threads[READERS], writer_threads[WRITERS];
    int reader_ids[READERS], writer_ids[WRITERS];
 
    // Initialize mutex and semaphore
    pthread_mutex_init(&mutex, NULL);
    sem_init(&rw_mutex, 0, 1);
 
    // Create reader threads
    for (int i = 0; i < READERS; i++) {
        reader_ids[i] = i + 1;
        pthread_create(&reader_threads[i], NULL, reader, &reader_ids[i]);
    }
 
    // Create writer threads
    for (int i = 0; i < WRITERS; i++) {
        writer_ids[i] = i + 1;
        pthread_create(&writer_threads[i], NULL, writer, &writer_ids[i]);
    }
 
    // Join threads
    for (int i = 0; i < READERS; i++) {
        pthread_join(reader_threads[i], NULL);
    }
    for (int i = 0; i < WRITERS; i++) {
        pthread_join(writer_threads[i], NULL);
    }
 
    // Destroy mutex and semaphore
    pthread_mutex_destroy(&mutex);
    sem_destroy(&rw_mutex);
 
    return 0;
}

Setup and Run

  1. Save the code as reader_writer.c.
  2. Compile the program using any C compiler (e.g., gcc).
  3. Run the compiled executable file.
  4. Observe the reader and writer threads accessing the shared resource with reader priority.

Example

gcc -o reader_writer reader_writer.c -lpthread
./reader_writer

Explanation

  • The program simulates multiple reader and writer threads accessing a shared resource (an integer value).
  • Mutex (mutex) is used to provide mutual exclusion between threads accessing shared variables.
  • Semaphore (rw_mutex) is used to enforce reader priority, allowing multiple readers to access the resource simultaneously while ensuring that only one writer can access the resource at a time.
  • Readers increment a shared integer value, simulating reading, while writers increment the value, simulating writing.
  • By running this program, you will observe the synchronization and mutual exclusion mechanisms implemented using mutex and semaphore to solve the reader-writer problem with reader priority.

Contact

For any questions or clarifications, please contact Parth Sali at parthsali04@gmail.com.