Say I've got that program that uses sem_timedwait
in order to wait for 100 ms (get current time, add 100 ms, use the result as abs_timeout
, cf. man page). Now it happens that the system time gets set by an external process (ntp) while waiting for the semaphore.
If we have bad luck, the system time gets set to say 2 days in the past. This would cause sem_timedwait
to wait for 2 days and 100 ms.
Is there a way to get around this issue?
You can use condition variables instead, and choose the monotonic clock as the reference clock. Semaphores are a bit old-school, I would avoid using them in new applications. You can easily implement semaphores using condition variables and mutexes if you like.
pthread_condattr_t cattr;
pthread_condattr_init(&cattr);
pthread_condattr_setclock(&cattr, CLOCK_MONOTONIC);
pthread_cond_t cond;
pthread_cond_init(&cond, &cattr);
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
ts.tv_nsec += 100000000;
if (ts.tv_nsec >= 1000000000) {
ts.tv_nsec -= 1000000000;
ts.tv_sec += 1;
}
int r = pthread_cond_timedwait(&cond, &mutex, &ts);
if (r == ETIMEDOUT) {
// ...
} else {
// ...
}
The monotonic clock is "not affected by discontinuous jumps in the system time" (man clock_gettime), so it is exactly what you want for this kind of application.
You said,
Now it happens that the system time gets set by an external process (ntp) while waiting for the semaphore.
But the situation is worse than that... the system clock might be adjusted after you call clock_gettime()
but before you call sem_timedwait()
... so as far as it knows, you wanted sem_timedwait()
to wait two days.
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