title: How does this pthread_cond_wait() example work?
body: <p>I got the below code from this website:</p>
  
  <p><a href="https://computing.llnl.gov/tutorials/pthreads/#Abstract" rel="nofollow">https://computing.llnl.gov/tutorials/pthreads/#Abstract</a></p>
  
  <blockquote>
    <p>This simple example code demonstrates the use of several Pthread
    condition variable routines. The main routine creates three threads.
    Two of the threads perform work and update a "count" variable. The
    third thread waits until the count variable reaches a specified value.</p>
  </blockquote>
  
  <p>My question is- how does the below code ensure that one of the two worker threads doesn't lock on the mutex before the watcher thread locks on it? If this was to happen, the watcher thread would be locked out and <code>pthread_cond_wait(&amp;count_threshold_cv, &amp;count_mutex)</code> would never get called?</p>
  
  <p>I am under the assumption <code>pthread_create()</code> actually begins the thread too. Is the only reason this works because the <code>pthread_create()</code> for the watcher thread begins before the <code>pthread_create()</code> for the two worker threads?! Surely this is not cast-iron and the scheduling could cause a worker thread to begin before the watcher thread? Even the compiler could potentially re-order these lines of code?</p>
  
  <pre><code>#include &lt;pthread.h&gt;
  #include &lt;stdio.h&gt;
  #include &lt;stdlib.h&gt;
  
  #define NUM_THREADS  3
  #define TCOUNT 10
  #define COUNT_LIMIT 12
  
  int     count = 0;
  int     thread_ids[3] = {0,1,2};
  pthread_mutex_t count_mutex;
  pthread_cond_t count_threshold_cv;
  
  void *inc_count(void *t) 
  {
    int i;
    long my_id = (long)t;
  
    for (i=0; i&lt;TCOUNT; i++) {
      pthread_mutex_lock(&amp;count_mutex);
      count++;
  
      /* 
      Check the value of count and signal waiting thread when condition is
      reached.  Note that this occurs while mutex is locked. 
      */
      if (count == COUNT_LIMIT) {
        pthread_cond_signal(&amp;count_threshold_cv);
        printf("inc_count(): thread %ld, count = %d  Threshold reached.\n", 
               my_id, count);
        }
      printf("inc_count(): thread %ld, count = %d, unlocking mutex\n", 
         my_id, count);
      pthread_mutex_unlock(&amp;count_mutex);
  
      /* Do some "work" so threads can alternate on mutex lock */
      sleep(1);
      }
    pthread_exit(NULL);
  }
  
  void *watch_count(void *t) 
  {
    long my_id = (long)t;
  
    printf("Starting watch_count(): thread %ld\n", my_id);
  
    /*
    Lock mutex and wait for signal.  Note that the pthread_cond_wait 
    routine will automatically and atomically unlock mutex while it waits. 
    Also, note that if COUNT_LIMIT is reached before this routine is run by
    the waiting thread, the loop will be skipped to prevent pthread_cond_wait
    from never returning. 
    */
    pthread_mutex_lock(&amp;count_mutex);
    while (count&lt;COUNT_LIMIT) {
      pthread_cond_wait(&amp;count_threshold_cv, &amp;count_mutex);
      printf("watch_count(): thread %ld Condition signal received.\n", my_id);
      count += 125;
      printf("watch_count(): thread %ld count now = %d.\n", my_id, count);
      }
    pthread_mutex_unlock(&amp;count_mutex);
    pthread_exit(NULL);
  }
  
  int main (int argc, char *argv[])
  {
    int i, rc;
    long t1=1, t2=2, t3=3;
    pthread_t threads[3];
    pthread_attr_t attr;
  
    /* Initialize mutex and condition variable objects */
    pthread_mutex_init(&amp;count_mutex, NULL);
    pthread_cond_init (&amp;count_threshold_cv, NULL);
  
    /* For portability, explicitly create threads in a joinable state */
    pthread_attr_init(&amp;attr);
    pthread_attr_setdetachstate(&amp;attr, PTHREAD_CREATE_JOINABLE);
    pthread_create(&amp;threads[0], &amp;attr, watch_count, (void *)t1);
    pthread_create(&amp;threads[1], &amp;attr, inc_count, (void *)t2);
    pthread_create(&amp;threads[2], &amp;attr, inc_count, (void *)t3);
  
    /* Wait for all threads to complete */
    for (i=0; i&lt;NUM_THREADS; i++) {
      pthread_join(threads[i], NULL);
    }
    printf ("Main(): Waited on %d  threads. Done.\n", NUM_THREADS);
  
    /* Clean up and exit */
    pthread_attr_destroy(&amp;attr);
    pthread_mutex_destroy(&amp;count_mutex);
    pthread_cond_destroy(&amp;count_threshold_cv);
    pthread_exit(NULL);
  
  }
  </code></pre>