C Program to Demonstrates use of reader/writer lock

How to write a C Program to Demonstrates use of reader/writer lock in C Programming Language ?


Solution:

  1. /* Demonstrates use of reader/writer lock*/
  2.  
  3. #include <stdlib.h>
  4. #include <pthread.h>
  5.  
  6. struct job {
  7.         struct job *j_next;
  8.         struct job *j_prev;
  9.         pthread_t   j_id;   /* tells which thread handles this job */
  10.         /* ... more stuff here ... */
  11. };
  12.  
  13. struct queue {
  14.         struct job      *q_head;
  15.         struct job      *q_tail;
  16.         pthread_rwlock_t q_lock;
  17. };
  18.  
  19. /*
  20.  * Initialize a queue.
  21.  */
  22. int queue_init(struct queue *qp)
  23. {
  24.         int err;
  25.  
  26.         qp->q_head = NULL;
  27.         qp->q_tail = NULL;
  28.         err = pthread_rwlock_init(&qp->q_lock, NULL);
  29.         if (err != 0)
  30.                 return(err);
  31.  
  32.         /* ... continue initialization ... */
  33.  
  34.         return(0);
  35. }
  36.  
  37. /*
  38.  * Insert a job at the head of the queue.
  39.  */
  40. void job_insert(struct queue *qp, struct job *jp)
  41. {
  42.         pthread_rwlock_wrlock(&qp->q_lock);
  43.         jp->j_next = qp->q_head;
  44.         jp->j_prev = NULL;
  45.         if (qp->q_head != NULL)
  46.                 qp->q_head->j_prev = jp;
  47.         else
  48.                 qp->q_tail = jp;        /* list was empty */
  49.         qp->q_head = jp;
  50.         pthread_rwlock_unlock(&qp->q_lock);
  51. }
  52.  
  53. /*
  54.  * Append a job on the tail of the queue.
  55.  */
  56. void job_append(struct queue *qp, struct job *jp)
  57. {
  58.         pthread_rwlock_wrlock(&qp->q_lock);
  59.         jp->j_next = NULL;
  60.         jp->j_prev = qp->q_tail;
  61.         if (qp->q_tail != NULL)
  62.                 qp->q_tail->j_next = jp;
  63.         else
  64.                 qp->q_head = jp;        /* list was empty */
  65.         qp->q_tail = jp;
  66.         pthread_rwlock_unlock(&qp->q_lock);
  67. }
  68.  
  69. /*
  70.  * Remove the given job from a queue.
  71.  */
  72. void job_remove(struct queue *qp, struct job *jp)
  73. {
  74.         pthread_rwlock_wrlock(&qp->q_lock);
  75.         if (jp == qp->q_head) {
  76.                 qp->q_head = jp->j_next;
  77.                 if (qp->q_tail == jp)
  78.                         qp->q_tail = NULL;
  79.         } else if (jp == qp->q_tail) {
  80.                 qp->q_tail = jp->j_prev;
  81.                 if (qp->q_head == jp)
  82.                         qp->q_head = NULL;
  83.         } else {
  84.                 jp->j_prev->j_next = jp->j_next;
  85.                 jp->j_next->j_prev = jp->j_prev;
  86.         }
  87.         pthread_rwlock_unlock(&qp->q_lock);
  88. }
  89.  
  90. /*
  91.  * Find a job for the given thread ID.
  92.  */
  93. struct job *job_find(struct queue *qp, pthread_t id)
  94. {
  95.         struct job *jp;
  96.  
  97.         if (pthread_rwlock_rdlock(&qp->q_lock) != 0)
  98.                 return(NULL);
  99.  
  100.         for (jp = qp->q_head; jp != NULL; jp = jp->j_next)
  101.                 if (pthread_equal(jp->j_id, id))
  102.                         break;
  103.  
  104.         pthread_rwlock_unlock(&qp->q_lock);
  105.         return(jp);
  106. }


Learn More :