title: reader/writer lock in pthread
body: <p>I'm learning pthread and came across reader writer lock. The scenario is very simple; a global variable being shared by all the threads, reader keeps printing the current value of that same global variable, while writer will update the same variable. I can achieve this synchronization by using two mutexes (pthread_mutex_t), but I want to use "one" reader-writer lock for achieving this same result. However, with one reader-writer lock, as can be seen here(output of the program, below), reader only sees the first value of x and doesn't sees any updates to the global variable. Please throw some light here.</p>
  
  <p>Code:</p>
  
  <pre><code>#include &lt;stdio.h&gt;
  #include &lt;errno.h&gt;
  #include &lt;stdlib.h&gt;
  #include &lt;pthread.h&gt;
  #include &lt;poll.h&gt;
  
  #define ACCESS_ONCE(x) (*(volatile typeof(x) *)&amp;(x))
  
  int x = 0;
  
  pthread_rwlock_t lock_rw = PTHREAD_RWLOCK_INITIALIZER;
  
  void *reader_thread(void *arg)
  {
      int i;
      int newx, oldx;
      newx = oldx = -1;
  
      pthread_rwlock_t *p = (pthread_rwlock_t *)arg;
  
      if (pthread_rwlock_rdlock(p) != 0) {
          perror("reader_thread: pthread_rwlock_rdlock error");
          exit(__LINE__);
      }
  
      for (i = 0; i &lt; 100; i++) {
          newx = ACCESS_ONCE(x);
          if (newx != oldx) {
              printf("reader_lock: x: %d\n",x);
          }
          oldx = newx;
          poll(NULL, 0, 1);
      }
  
      if (pthread_rwlock_unlock(p) != 0) {
          perror("reader thread: pthred_rwlock_unlock error");
          exit(__LINE__);
      }
  
      return NULL;
  }
  
  void *writer_thread(void *arg)
  {
      int i;
      pthread_rwlock_t *p = (pthread_rwlock_t *)arg;
  
      if (pthread_rwlock_wrlock(p) != 0) {
          perror("writer thread: pthread_rwlock_wrlock error");
          exit(__LINE__);
      }
  
      for (i = 0; i &lt; 3; i++) {
          ACCESS_ONCE(x)++;
          poll(NULL, 0, 5);
      }
  
      if (pthread_rwlock_unlock(p) != 0) {
          perror("writer thread: pthread_rwlock_unlock error");
          exit(__LINE__);
      }
  
      return NULL;
  }
  
  int main(void)
  {
      pthread_t tid1, tid2;
      void *vp;
      if (pthread_create(&amp;tid1, NULL, reader_thread, &amp;lock_rw) != 0) {
          perror("pthread_create error");
          exit (__LINE__);
      }
  
      if (pthread_create(&amp;tid2, NULL, writer_thread, &amp;lock_rw) != 0) {
          perror("pthread_create error");
          exit (__LINE__);
      }
  
      //wait for the thread to complete
      if (pthread_join(tid1, &amp;vp) != 0) {
          perror("pthread_join error");
          exit (__LINE__);
      }
  
      if (pthread_join(tid2, &amp;vp) != 0) {
          perror("pthread_join error");
          exit (__LINE__);
      }
  
      printf("Parent process sees x: %d\n",x);
      return 0;
  }
  </code></pre>
  
  <blockquote>
    <p>gcc pthread_rwlock.c -o rwlock -pthread -Wall -Werror</p>
    
    <p>./rwlock</p>
    
    <p>reader_lock: x: 0</p>
    
    <p>Parent process sees x: 3</p>
  </blockquote>