14

The pthread_cond_timedwait function needs an absolute time in a time timespec structure.

What time function I'm suppose to use to obtain the absolute time. I saw a lot of example on the web and I found almost all time function used. (ftime, clock, gettimeofday, clock_gettime (with all possible CLOCK_...).

The pthread_cond_timedwait uses an absolute time. Will this waiting time affected by changing the time of the machine? Also if I get the absolute time with one of the time function, if the time of the machine change between the get and the addition of the delta time this will affect the wait time? Is there a possibility to wait for an event with a relative time instead?

Vincent
  • 2,712
  • 5
  • 24
  • 27

3 Answers3

17

The function to use is clock_gettime() with the clock id of the condition variable. This clock id is CLOCK_REALTIME by default but can be changed (such as to CLOCK_MONOTONIC) by initializing the condition variable with a pthread_condattr_t on which pthread_condattr_setclock() has been called.

Using time() is not a good idea because this is not guaranteed to equal tv_sec of a clock_gettime(CLOCK_REALTIME). In some cases this can cause your program to busy-wait for time() to reach the second that was already reached by clock_gettime(CLOCK_REALTIME) a short while ago.

jilles
  • 10,509
  • 2
  • 26
  • 39
  • 6
    clock_gettime(CLOCK_MONOTONIC) is the way to get a time that is only increasing thus unaffected by changing the time of the system. Initializing the condition's attribute with pthread_condattr_setclock with CLOCK_MONOTONIC will make pthread_cond_timedwait wait with a relative time. – Vincent Jan 04 '11 at 19:12
2

I've used clock_gettime with CLOCK_REALTIME myself. That should work satisfactorily and allow you to easily create an absolute timespec to timeout at.

Indeed there's a possibility that the machine time will advance while you do the wait setup. In general if you're waiting for a small enough amount of time that this would matter, you won't be getting as close to your requested wakeup time as you hope anyway. If your requested time has already passed by the time the timedwait call is made, it should just wake up immediately.

Solaris provides pthread_cond_reltimedwait_np, (np to mean non-portable) but I'm not aware of any such function on Linux. I'd suggest just waiting on the absolute time and, if needed, implementing a relative wait yourself.

Mark B
  • 95,107
  • 10
  • 109
  • 188
  • 1
    It's a pity there isn't a `CLOCK_MONOTONIC`-based version. – caf Jun 10 '10 at 00:56
  • Is the clock_gettime with CLOCK_REALTIME is "heavy" on the low level resources? – Vincent Jun 11 '10 at 13:08
  • I don't believe so, but the best way to find out is to profile your specific application and if it shows that the `clock_gettime` is a significant problem only then try to optimize it. – Mark B Jun 11 '10 at 13:36
  • According to your second paragraph, the software can behave differently close to the time change, this can be very dangerous. I think that pthread_cond_timedwait should be avoided. – Vincent Jun 14 '10 at 14:15
  • @Vincent Indeed it can behave differently if for example someone resets the system clock. On the other hand if your software expects particular wakeup behavior/timing you will almost certainly see other problems due to assumptions at some point, even if you were able to use a relative wakeup time. – Mark B Jun 14 '10 at 14:55
  • 3
    @caf You can call [`pthread_condattr_setclock`][^1] beforehand to use `CLOCK_MONOTONIC` with this function. [^1]: http://pubs.opengroup.org/onlinepubs/009695399/functions/pthread_condattr_setclock.html – Left For Archive Jul 02 '12 at 20:08
  • @LnxPrgr3: Excellent! Thanks for letting me know about that. – caf Jul 03 '12 at 00:19
-1

timespec is just a time in seconds (time_t) with additional nanoseconds. You can use relative time with cond_relative_timed_wait.

To obtain current system time in time_t form call time(NULL); from "time.h". More accurate would be to use

timespec ts;
clock_gettime(CLOCK_REALTIME, &ts);

which will return also nanoseconds.

Other functions can be used as well but the final result must be converted to number of seconds and number of nanoseconds.

adf88
  • 4,277
  • 1
  • 23
  • 21
  • 2
    I cannot find the definition of the function cond_relative_timed_wait(). Where it is defined? – Vincent Jun 09 '10 at 15:40