pthreads Readers/Writers Lock C Program

how to write a C Program to pthreads Readers/Writers Lock in C Programming Language ?


Solution:
  1.  
  2. /*
  3.  * a pthreads readers/writers lock
  4.  * based on the code in section 5.6.1 of Dahlin/Anderson
  5.  */
  6.  
  7. #include <pthread.h>
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <assert.h>
  11.  
  12. #define NUMOPS 1000
  13.  
  14. typedef struct {
  15.   // sync. variables
  16.   pthread_mutex_t lock;
  17.   pthread_cond_t read_go;
  18.   pthread_cond_t write_go;
  19.  
  20.   // state variables
  21.   int active_readers;
  22.   int active_writers;
  23.   int waiting_readers;
  24.   int waiting_writers;
  25. } RWLOCK;
  26.  
  27. RWLOCK *rwlock_create() {
  28.   RWLOCK *rwlock;
  29.   rwlock = malloc(sizeof(RWLOCK));
  30.   assert(rwlock != NULL);
  31.   pthread_mutex_init(&rwlock->lock, NULL);
  32.   pthread_cond_init(&rwlock->read_go, NULL);
  33.   pthread_cond_init(&rwlock->write_go, NULL);
  34.   rwlock->active_readers = 0;
  35.   rwlock->active_writers = 0;
  36.   rwlock->waiting_readers = 0;
  37.   rwlock->waiting_writers = 0;
  38.   return(rwlock);
  39. }
  40.  
  41. void print_state(char *id, RWLOCK *rwlock) {
  42.   if (0) {
  43.     printf("%s: wr=%d, ar=%d, ww=%d, aw=%d\n", id,
  44.          rwlock->waiting_readers, rwlock->active_readers,
  45.          rwlock->waiting_writers, rwlock->active_writers);
  46.   }
  47. }
  48.  
  49. void start_read(RWLOCK *rwlock) {
  50.   pthread_mutex_lock(&rwlock->lock);
  51.   print_state("sr1", rwlock);
  52.  
  53.   rwlock->waiting_readers++;
  54.  
  55.   while (&rwlock->active_writers > 0) {
  56.     pthread_cond_wait(&rwlock->read_go, &rwlock->lock);
  57.   }
  58.  
  59.   rwlock->waiting_readers--;
  60.   rwlock->active_readers++;
  61.  
  62.   print_state("sr2", rwlock);
  63.   pthread_mutex_unlock(&rwlock->lock);
  64. }
  65.  
  66. void done_read(RWLOCK *rwlock) {
  67.   pthread_mutex_lock(&rwlock->lock);
  68.   print_state("dr1", rwlock);
  69.  
  70.   rwlock->active_readers--;
  71.  
  72.   if (&rwlock->active_readers == 0) {
  73.     pthread_cond_signal(&rwlock->write_go);
  74.     pthread_cond_signal(&rwlock->read_go);
  75.   }
  76.  
  77.   print_state("dr2", rwlock);
  78.   pthread_mutex_unlock(&rwlock->lock);
  79. }
  80.  
  81. void start_write(RWLOCK *rwlock) {
  82.   pthread_mutex_lock(&rwlock->lock);
  83.   print_state("sw1", rwlock);
  84.  
  85.   rwlock->waiting_writers++;
  86.  
  87.   while (rwlock->active_readers > 0 || rwlock->active_writers > 0) {
  88.     pthread_cond_wait(&rwlock->write_go, &rwlock->lock);
  89.   }
  90.  
  91.   rwlock->waiting_writers--;
  92.   rwlock->active_writers++;
  93.  
  94.   print_state("sw2", rwlock);
  95.   pthread_mutex_unlock(&rwlock->lock);
  96. }
  97.  
  98. void done_write(RWLOCK *rwlock) {
  99.   pthread_mutex_lock(&rwlock->lock);
  100.   print_state("dw1", rwlock);
  101.  
  102.   rwlock->active_writers--;
  103.  
  104.   if (rwlock->active_writers == 0) {
  105.     pthread_cond_signal(&rwlock->read_go);
  106.     pthread_cond_signal(&rwlock->write_go);
  107.   }
  108.  
  109.   print_state("dw2", rwlock);
  110.   pthread_mutex_unlock(&rwlock->lock);
  111. }
  112.  
  113. // reader: does a bunch of reads
  114. void *reader(void *arg) {
  115.   RWLOCK *rwlock = (RWLOCK *)arg;
  116.   int i;
  117.   for (= 0; i < NUMOPS; i++) {
  118.     start_read(rwlock);
  119.     printf("sr\n");
  120.     printf("dr\n");
  121.     done_read(rwlock);
  122.   }
  123.   pthread_exit(NULL);
  124. }
  125.  
  126. // writer: does a bunch of writes
  127. void *writer(void *arg) {
  128.   RWLOCK *rwlock = (RWLOCK *)arg;
  129.   int i;
  130.   for (= 0; i < NUMOPS; i++) {
  131.     start_write(rwlock);
  132.     printf("sw\n");
  133.     printf("dw\n");
  134.     done_write(rwlock);
  135.   }
  136.   pthread_exit(NULL);
  137. }
  138.  
  139. // test the read-write lock
  140. int main(int argc, char *argv[]) {
  141.   pthread_t r1,r2,r3,w1,w2;
  142.  
  143.   RWLOCK *rwlock = rwlock_create();
  144.  
  145.   // create some reading and writing threads
  146.   pthread_create(&r1, NULL, reader, (void *)rwlock);  
  147.   pthread_create(&r2, NULL, reader, (void *)rwlock);  
  148.   pthread_create(&r3, NULL, reader, (void *)rwlock);  
  149.   pthread_create(&w1, NULL, writer, (void *)rwlock);  
  150.   pthread_create(&w2, NULL, writer, (void *)rwlock);  
  151.  
  152.   pthread_exit(NULL);
  153. }


Learn More :