As I understand it, pthread_cond_timedwait is to be used by taking current time, then calculating absolute time when pthread_cond_timedwait should exit if condition is not signalled.
Is there a simple way to use this function to reliably perform a periodic task (the problem being changes in time between the point where current time is taken and call to pthread_cond_timedwait)?
I have a periodic task that should run ~every second.
do {
pthread_mutex_lock(mutex);
tx = gettimeofday + 1 second;
do_some_simple_periodic_task();
pthread_cond_timedwait(condition, mutex, tx);
pthread_mutex_unlock(mutex);
} while (!some_exit_condition);
Condition is signalled if context (including some_exit_condition) is updated.
Is there a way to use monotonic timer or something similar with this? If not, what is the use case for pthread_cond_timedwait at all? Only for cases, where you don't care about additional hour of delay?
I have seen a solution where another thread signals this one periodically (How to make pthread_cond_timedwait() robust against system clock manipulations?), but it seems like a hack.
Is there a different & better way to make thread sleep for some interval (not prone to wall clock changes) but respond immediately to external condition?
The pthread_cond_timedwait() function atomically unlocks the mutex and performs the wait for the condition. In this case, atomically means with respect to the mutex and the condition variable and other access by threads to those objects through the pthread condition variable interfaces.
The pthread_cond_broadcast() function shall unblock all threads currently blocked on the specified condition variable cond. The pthread_cond_signal() function shall unblock at least one of the threads that are blocked on the specified condition variable cond (if any threads are blocked on cond).
You can set the clock type used by pthread_cond_timedwait() by setting attributes when initializing the condition variable:
pthread_condattr_t cond_attr;
pthread_cond_t cond;
errno = pthread_condattr_init (&cond_attr);
if (errno) {
perror ("pthread_condattr_init");
return -1;
}
errno = pthread_condattr_setclock (&cond_attr, CLOCK_MONOTONIC);
if (errno) {
perror ("pthread_condattr_setclock");
return -1;
}
errno = pthread_cond_init (&cond, &cond_attr);
if (errno) {
perror ("pthread_cond_init");
return -1;
}
And then use time from CLOCK_MONOTONIC for timeout:
struct timespec timeout;
clock_gettime (CLOCK_MONOTONIC, &timeout);
timeout.tv_sec += 1;
// pthread_cond_timedwait (..., timeout);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With