Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When to use pthread condition variables?

Tags:

c

linux

pthreads

pthread question:

it appears that a condition variable only works if pthread_cond_wait is called before the other thread calls pthread_cond_notify. If notify somehow happens before wait then wait will be stuck.

My question is: when should condition variables be used?

The scheduler can preempt threads and a notify may happen before wait.

Waiting on semaphores does not have this problem -- these have a counter.

When is a conditional variable better than a semaphore?

Here is a test:

File condvar.c

#include <pthread.h> #include <stdio.h> #include <stdlib.h>  // test of conditional variables; // if cond-var is notified before wait starts, then wait never wakes up !!! // better to use semaphores than this crap.  pthread_mutex_t cond_var_lock =  PTHREAD_MUTEX_INITIALIZER;  pthread_cond_t cond_var = PTHREAD_COND_INITIALIZER;  int wait_first = 1;  void *tfunc(void *arg) {     (void) arg;      if (!wait_first)         sleep(1);      fprintf(stderr,"on enter cond_var_lock %lx\n", pthread_self());     pthread_mutex_lock( &cond_var_lock);     fprintf(stderr,"before pthread_cond_wait %lx\n", pthread_self());     pthread_cond_wait( &cond_var, &cond_var_lock);     fprintf(stderr,"after pthread_cond_wait %lx\n", pthread_self());     pthread_mutex_unlock( &cond_var_lock);     fprintf(stderr,"after exit cond_var_lock %lx\n", pthread_self());      return 0; }  int main(int argc, char *argv[]) {     pthread_t th;      if (argc > 0)      wait_first = atoi( argv[1] );      if (wait_first)     {         fprintf(stderr,"********* Wait first ***********\n");     } else {         fprintf(stderr,"********* Notify first *********\n");     }       pthread_create( &th, 0, tfunc, 0 );      if (wait_first)     {         sleep(1);     }       fprintf(stderr, "! on enter cond_var_lock %lx\n", pthread_self());     pthread_mutex_lock( &cond_var_lock);     fprintf(stderr, "! before pthread_cond_signal %lx\n", pthread_self());     pthread_cond_signal( &cond_var );     fprintf(stderr, "! after pthread_cond_signal %lx\n", pthread_self());     pthread_mutex_unlock( &cond_var_lock);     fprintf(stderr, "! after exit cond_var_lock %lx\n", pthread_self());      sleep(5);     return 0;     } 

File test.sh

#!/bin/sh  set -e set -x  gcc condvar.c -o condvar -lpthread  ./condvar 1  ./condvar 0 

Test output

Output:  + gcc condvar.c -o condvar -lpthread + ./condvar 1 ********* Wait first *********** on enter cond_var_lock b7779b70 before pthread_cond_wait b7779b70 ! on enter cond_var_lock b777a6c0 ! before pthread_cond_signal b777a6c0 ! after pthread_cond_signal b777a6c0 ! after exit cond_var_lock b777a6c0 after pthread_cond_wait b7779b70 after exit cond_var_lock b7779b70 + ./condvar 0 ********* Notify first ********* ! on enter cond_var_lock b785c6c0 ! before pthread_cond_signal b785c6c0 ! after pthread_cond_signal b785c6c0 ! after exit cond_var_lock b785c6c0 on enter cond_var_lock b785bb70 before pthread_cond_wait b785bb70 
like image 206
MichaelMoser Avatar asked Dec 25 '13 11:12

MichaelMoser


People also ask

What is pthread condition variables?

Explanation: When you want to sleep a thread, condition variable can be used. In C under Linux, there is a function pthread_cond_wait() to wait or sleep. On the other hand, there is a function pthread_cond_signal() to wake up sleeping or waiting thread. Threads can wait on a condition variable.

What are condition variables used for?

Condition variables are synchronization primitives that enable threads to wait until a particular condition occurs. Condition variables are user-mode objects that cannot be shared across processes. Condition variables enable threads to atomically release a lock and enter the sleeping state.

Why do we need to use conditional variables in pthread with a mutex lock?

It's just the way that condition variables are (or were originally) implemented. The mutex is used to protect the condition variable itself. That's why you need it locked before you do a wait. The wait will "atomically" unlock the mutex, allowing others access to the condition variable (for signalling).

Why do condition variables need mutex?

While mutex implement synchronization by controlling thread access to data, condition variables allow threads to synchronize based upon the actual value of data. Without condition variables, the programmer would need to have threads continually polling (possibly in a critical section), to check if the condition is met.


1 Answers

Condition variables should be used as a place to wait and be notified. They are not the condition itself and they are not events. The condition is contained in the surrounding programming logic. The typical usage pattern of condition variables is

// safely examine the condition, prevent other threads from // altering it pthread_mutex_lock (&lock); while ( SOME-CONDITION is false)     pthread_cond_wait (&cond, &lock);  // Do whatever you need to do when condition becomes true do_stuff(); pthread_mutex_unlock (&lock); 

On the other hand, a thread, signaling the condition variable, typically looks like

// ensure we have exclusive access to whathever comprises the condition pthread_mutex_lock (&lock);  ALTER-CONDITION  // Wakeup at least one of the threads that are waiting on the condition (if any) pthread_cond_signal (&cond);  // allow others to proceed pthread_mutex_unlock (&lock) 
like image 182
chill Avatar answered Sep 20 '22 23:09

chill