Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

pthread_cond_timedwait for periodic tasks & wall clock changes

Tags:

c

pthreads

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?

like image 315
dbrank0 Avatar asked Sep 14 '17 12:09

dbrank0


People also ask

How does pthread_ cond_ timedwait work?

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.

What is Pthread_cond_broadcast?

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).


Video Answer


1 Answers

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);
like image 183
Erki Aring Avatar answered Oct 27 '22 00:10

Erki Aring