C Programming: Understanding Read-Write Locks šŸŽÆ

beginner
24 min

C Programming: Understanding Read-Write Locks šŸŽÆ

Welcome to a deep dive into C Programming! Today, let's explore Read-Write Locks, an essential concept for managing concurrent access to shared data. šŸ’”

What are Read-Write Locks? šŸ“

Read-Write Locks (RW Locks) are synchronization primitives that allow multiple read operations to be performed concurrently while preventing write operations. This is crucial for enhancing the performance of multi-threaded programs by reducing contention.

The Need for Read-Write Locks āœ…

Imagine a library where multiple readers can access a book simultaneously but only one person can borrow or return a book at a time. Read-Write Locks mimic this scenario in the world of programming.

Understanding Read and Write Locks šŸ“

  • Read Lock (RL): Granted to threads that only read shared data. Multiple threads can hold a read lock simultaneously.
  • Write Lock (WL): Granted to threads that write or modify shared data. Only one thread can hold a write lock at a time.

Implementing Read-Write Locks šŸ’”

C doesn't provide a built-in Read-Write Lock mechanism. However, we can create our own using mutexes and condition variables.

Here's a simple implementation:

c
#include <pthread.h> #include <stdbool.h> typedef struct { pthread_mutex_t rw_mutex; pthread_cond_t readers; pthread_cond_t writer; bool writing; } rwlock_t; void rwlock_init(rwlock_t *lock) { pthread_mutex_init(&lock->rw_mutex, NULL); pthread_cond_init(&lock->readers, NULL); pthread_cond_init(&lock->writer, NULL); lock->writing = false; } void rwlock_wrlock(rwlock_t *lock) { pthread_mutex_lock(&lock->rw_mutex); while (lock->writing) { pthread_cond_wait(&lock->writer, &lock->rw_mutex); } lock->writing = true; } void rwlock_rdlock(rwlock_t *lock) { pthread_mutex_lock(&lock->rw_mutex); while (lock->writing) { pthread_cond_wait(&lock->readers, &lock->rw_mutex); } } void rwlock_unlock(rwlock_t *lock) { pthread_mutex_unlock(&lock->rw_mutex); pthread_cond_broadcast(&lock->readers); lock->writing = false; }

šŸ“ Note: This implementation is basic and may not be suitable for high-load applications. For such cases, consider using more robust solutions like Google's RWLock.

Using Read-Write Locks in Practice šŸ’”

Now let's use our Read-Write Locks to manage a shared data structure, like a queue, in a multi-threaded environment.

c
#include <stdio.h> #include <pthread.h> #include <stdbool.h> #define NUM_THREADS 10 #define QUEUE_SIZE 5 typedef struct { int items[QUEUE_SIZE]; int head, tail; rwlock_t rw_lock; } queue_t; queue_t queue; void enqueue(int value) { rwlock_rdlock(&queue.rw_lock); if ((queue.tail + 1) % QUEUE_SIZE == queue.head) { rwlock_unlock(&queue.rw_lock); printf("Queue is full. Dropping item %d\n", value); return; } queue.items[queue.tail] = value; queue.tail = (queue.tail + 1) % QUEUE_SIZE; rwlock_unlock(&queue.rw_lock); rwlock_wrlock(&queue.rw_lock); printf("Enqueued item %d\n", value); rwlock_unlock(&queue.rw_lock); } int dequeue() { int value; rwlock_wrlock(&queue.rw_lock); if (queue.head == queue.tail) { rwlock_unlock(&queue.rw_lock); return -1; } value = queue.items[queue.head]; queue.head = (queue.head + 1) % QUEUE_SIZE; rwlock_unlock(&queue.rw_lock); rwlock_rdlock(&queue.rw_lock); printf("Dequeued item %d\n", value); rwlock_unlock(&queue.rw_lock); return value; } void *producer(void *arg) { for (int i = 0; i < 10; i++) { enqueue(i); sleep(1); } return NULL; } void *consumer(void *arg) { while (true) { int value = dequeue(); if (value == -1) break; printf("Consumed item %d\n", value); sleep(2); } return NULL; } int main() { rwlock_init(&queue.rw_lock); queue.head = queue.tail = 0; pthread_t producers[NUM_THREADS], consumers[NUM_THREADS]; for (int i = 0; i < NUM_THREADS; i++) { pthread_create(&producers[i], NULL, producer, NULL); pthread_create(&consumers[i], NULL, consumer, NULL); } for (int i = 0; i < NUM_THREADS; i++) { pthread_join(producers[i], NULL); pthread_join(consumers[i], NULL); } rwlock_destroy(&queue.rw_lock); return 0; }

Quiz šŸ“

Quick Quiz
Question 1 of 1

What is the purpose of Read-Write Locks in C Programming?