Thread: Understanding pthread_cond_wait() and pthread_cond_signal()

  1. #1
    Registered User
    Join Date
    Jan 2007
    Posts
    113

    Understanding pthread_cond_wait() and pthread_cond_signal()

    Hi all

    I was trying to understand pthread cond and signal api functionality. So from online tutorials, I found that when a thread is want to wait for any condition to satisfy, it will go into wait mode and if some other thread fulfill that condition, it will send signal.
    Below is the test code. I try to debug but it was fluctuating between functions. I have below understanding and also some doubts which I want you guys help to understand.

    Doubt 1:

    When a thread T1 calls pthread_cond_wait(&count_threshold_cv, &count_mutex); , it means that mutex which was locked by T1 thread will be released . The release mutex is used by T2 thread and it accuire locks and once done, send signal to T1 thread and T2release the mutex.
    T1 then wake up and it again accuire lock ( this is automatically done ) and process further and then release the mutex. So the steps which happen are as below in sequence:

    a) T1 accuqire lock
    b) T1 check condition and go to wait mode
    c) T1 release the mutex
    d) T2 accuqire mutex lock
    e) T2 perform action
    f) T2 send signal to T1
    g) T1 wake up but wait for Mutex
    h) T2 complete the work and release Mutex
    i) T1 get the lock and proceed further.


    Is the above sequence correct?


    Doubt 2:

    Is count_threshold_cv variable is also released when Thread T1 goes to wait condition? I beleive it is released and I have used that in in_test() function. Am I correct?

    Doubt 3:

    I have read on net, that always prefer while loop rather than if condition? What's the basic behind this?

    doubt 4:

    When we do cond_signal_broadcast(), is there any sequence the thread will wake up. I read somewhere that thread which wait first, will wake up first. I have tested that too in my code and that was true.
    Is this correct?



    Code:
     #include <stdio.h>
     #include <stdlib.h>
     #include <pthread.h>
    
     #define NUM_THREADS  4
     #define TCOUNT 10
     #define COUNT_LIMIT 12
     int     count = 0;
     pthread_mutex_t count_mutex;
     pthread_cond_t count_threshold_cv;
    
    
     void *in_test(void *t)
     {
        long my_id = (long)t;
    
        pthread_mutex_lock(&count_mutex);
    
    
        while ( count < COUNT_LIMIT )
        {
    
           printf("\n Will Wait for signal %d\n",  my_id );
           pthread_cond_wait(&count_threshold_cv, &count_mutex);
    
           printf("\n Recieved Signal in Test\n");
    
    
        }
    
          pthread_mutex_unlock(&count_mutex);
          printf ( "\n Test Successful for Thread %d\n",my_id );
    
          pthread_exit(NULL);
    
    
     }
    
     void *inc_count(void *t)
     {
       int i;
       long my_id = (long)t;
       for (i=0; i < TCOUNT; i++) {
         pthread_mutex_lock(&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) {
               printf("inc_count(): thread %ld, count = %d  Threshold reached. ",
                      my_id, count);
               //pthread_cond_signal(&count_threshold_cv);
    
               pthread_cond_broadcast(&count_threshold_cv);
    
               printf("Just sent signal.\n");
          }
    
           printf("inc_count(): thread %ld, count = %d, unlocking mutex\n",
                          my_id, count);
    
          pthread_mutex_unlock(&count_mutex);
          sleep(1);
         }
            pthread_exit(NULL);
     }
    
        void *watch_count(void *t)
        {
          long my_id = (long)t;
          printf("Starting watch_count(): thread %ld\n", my_id);
       
          pthread_mutex_lock(&count_mutex);
    
    
          while (count < COUNT_LIMIT) {
           printf("watch_count(): thread %ld Count= %d. Going into wait...\n", my_id,count);
           pthread_cond_wait(&count_threshold_cv, &count_mutex);
           printf("watch_count(): thread %ld Condition signal received. Count= %d\n", my_id,count);
           printf("watch_count(): thread %ld Updating the value of count...\n", my_id,count);
           count += 125;
           printf("watch_count(): thread %ld count now = %d.\n", my_id, count);
         }
           printf("watch_count(): thread %ld Unlocking mutex.\n", my_id);
           pthread_mutex_unlock(&count_mutex);
           pthread_exit(NULL);
         }
    
    
    
    
    
    
     int main(int argc, char *argv[])
     {
       int i, rc;
       long t1=1, t2=2, t3=3,t4=4;
       pthread_t threads[4];
       pthread_attr_t attr;
    
       /* Initialize mutex and condition variable objects */
         pthread_mutex_init(&count_mutex, NULL);
         pthread_cond_init (&count_threshold_cv, NULL);
    
       pthread_attr_init(&attr);
       pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
        rc =  pthread_create(&threads[0], &attr, watch_count, (void *)t1);
        if ( rc != 0 )
            printf("\n Error In Thread Creation");
    
        rc = pthread_create(&threads[1], &attr, inc_count, (void *)t2);
    
        if ( rc != 0 )
            printf("\n Error In Thread Creation");
    
    
       rc = pthread_create(&threads[2], &attr, inc_count, (void *)t3);
    
       if ( rc != 0 )
           printf("\n Error In Thread Creation");
    
       rc = pthread_create(&threads[3], &attr, in_test, (void *)t4);
    
       if ( rc != 0 )
           printf("\n Error In Thread Creation");
    
         for (i = 0; i < NUM_THREADS; i++) {
           pthread_join(threads[i], NULL);
         }
    
         /* Clean up and exit */
         pthread_attr_destroy(&attr);
         pthread_mutex_destroy(&count_mutex);
         pthread_cond_destroy(&count_threshold_cv);
         pthread_exit (NULL);
    
      }

  2. #2
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    >> Doubt 1:
    That is a possible sequence.

    >> Doubt 2:
    >> Doubt 3:
    When you call signal/broadcast it will only release threads that are currently blocked inside a wait call. In other words, if you call signal followed by a wait, the wait will block. This is why you should always have a predicate loop (while loop).
    pthread_cond_timedwait

    >> Doubt 4:
    pthread_cond_broadcast

    gg

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. PThreads - specifically pthread_cond_wait and pthread_cond_signal
    By FrankTheKneeMan in forum C Programming
    Replies: 5
    Last Post: 04-07-2011, 08:33 AM
  2. pthread_cond_wait for binary semaphores
    By homer_3 in forum C Programming
    Replies: 2
    Last Post: 10-09-2009, 02:27 PM
  3. pthread_cond_signal Q
    By homer_3 in forum C Programming
    Replies: 1
    Last Post: 09-22-2009, 11:50 AM
  4. A simple question about pthread_cond_wait()
    By meili100 in forum C++ Programming
    Replies: 6
    Last Post: 09-17-2008, 06:56 AM
  5. pthread_cond_wait() VS. sem_wait()
    By mynickmynick in forum C Programming
    Replies: 8
    Last Post: 05-07-2008, 10:28 AM