Condition Variables
A mutex is fine to prevent simultaneous access to a shared variable, but we need something else to let us go to sleep waiting for some condition to occur. Let's demonstrate this with an exampleBut,
we cannot call the Pthread function until we know that a thread has terminated. We first declare a global variable that counts the number of terminated threads and protect it with a mutex.
int ndone; /* number of terminated threads */
pthread_mutex_t ndone_mutex =
PTHREAD_MUTEX_INITIALIZER;
We then require that each thread increment this counter when it terminates, being careful to use the associated mutex.
void *
do_get_read (void *vptr)
{
...
Pthread_mutex_lock(&ndone_mutex);
ndone++;
Pthread_mutex_unlock(&ndone_mutex);
return(fptr); /* terminate thread */
}
A condition variable, in conjunction with a
mutex, provides this facility. The mutex provides mutual exclusion and the
condition variable provides a signaling mechanism.
In terms of Pthreads, a condition variable is a
variable of type pthread_cond_t. They are used with
the following two functions:
#include <pthread.h>
int pthread_cond_wait(pthread_cond_t *cptr,
pthread_mutex_t *mptr);
int pthread_cond_signal(pthread_cond_t *cptr);
Both return: 0 if OK, positive Exxx
value on error
The term "signal" in the second
function's name does not refer to a Unix SIGxxx signal.
Why is a mutex always associated with a
condition variable? The "condition" is normally the value of some
variable that is shared between the threads. The mutex is required to allow
this variable tobe set and tested by the different threads. For example, if we
did not have the mutex in the example code just shown, the main loop would test
it as follows:
/* Wait
for thread to terminate */ while (ndone == 0)
Pthread_cond_wait(&ndone_cond,
&ndone_mutex);
The thread would have to unlock and lock the
mutex and the code would look like the following:
/* Wait
for thread to terminate */ Pthread_mutex_lock(&ndone_mutex); while (ndone
== 0) {
Pthread_mutex_unlock(&ndone_mutex);
Pthread_cond_wait(&ndone_cond, &ndone_mutex);
Pthread_mutex_lock(&ndone_mutex);
}
#include <pthread.h>
int pthread_cond_broadcast (pthread_cond_t * cptr);
int pthread_cond_timedwait (pthread_cond_t * cptr, pthread_mutex_t *mptr,
const
struct timespec *abstime);
Both return: 0 if OK, positive Exxx
value on error
pthread_cond_timedwait lets a thread place a
limit on how long it will block. abstime is a timespec structure (as we defined
with the pselect function, that specifies the system time when the function
must return, even if the condition variable has not been signalled yet. If this
timeout occurs, ETIME is returned.
This time value is an absolute time; it is not
a time delta. That is, abstime is the system time—the number of seconds and
nanoseconds past January 1, 1970, UTC—when the function should return. This
differs from both select and pselect, which specify the number of seconds and
microseconds (nanoseconds for pselect) until some time in the future when the
function should return. The normal procedure is to call gettimeofday to obtain
the current time (as a timeval structure!), and copy this into a timespec
structure, adding in the desired time limit. For example,
struct timeval tv;
struct timespec ts;
if (gettimeofday(&tv, NULL) < 0)
err_sys("gettimeofday error");
ts.tv_sec
= tv.tv_sec + 5; /* 5 seconds in
future */
ts.tv_nsec = tv.tv_usec * 1000; /* microsec to
nanosec */
pthread_cond_timedwait( ..., &ts);
The advantage in using an absolute time instead
of a delta time is if the function prematurely returns (perhaps because of a
caught signal), the function can be called again, without having to change the
contents of the timespec structure. The disadvantage, however, is having to
call gettimeofday before the function can be called the first time.
The POSIX specification defines a clock_gettime
function that returns the current time as a timespec structure.
Related Topics
Privacy Policy, Terms and Conditions, DMCA Policy and Compliant
Copyright © 2018-2023 BrainKart.com; All Rights Reserved. Developed by Therithal info, Chennai.