...">

Pthread_cond_timedwait returns immediately

I have a strange problem. I have the following code:

dbg("condwait: timeout = %d, %d\n", abs_timeout->tv_sec, abs_timeout->tv_nsec); ret = pthread_cond_timedwait( &q->q_cond, &q->q_mtx, abs_timeout ); if (ret == ETIMEDOUT) { dbg("cond timed out\n"); return -ETIMEDOUT; } 

dbg calls gettimeofday before each line and adds a line with time. This leads to the following result:

  7.991151: condwait: timeout = 5, 705032704 7.991158: cond timed out 

As you can see, only 7 microseconds passed through two lines of debugging, but pthread_cond_timedwait returned ETIMEDOUT . How can this happen? I even tried to set the clock to something else while initializing the cond variable:

 int ret; ret = pthread_condattr_init(&attributes); if (ret != 0) printf("CONDATTR INIT FAILED: %d\n", ret); ret = pthread_condattr_setclock(&attributes, CLOCK_REALTIME); if (ret != 0) printf("SETCLOCK FAILED: %d\n", ret); ret = pthread_cond_init( &q->q_cond, &attributes ); if (ret != 0) printf("COND INIT FAILED: %d\n", ret); 

(none of the error messages are printed). I tried both CLOCK_REALTIME and CLOCK_MONOTONIC .

This code is part of the lock queue. I need such functionality that if nothing is delivered in this queue after 5 seconds, something else will happen. The mutex and cond are initialized, since the blocking queue works fine if I do not use pthread_cond_timedwait .

+6
c multithreading pthreads conditional system
source share
4 answers

pthread_cond_timedwait accepts absolute time, not relative time. You must make your wait time absolute by adding the current time to your timeout value.

+14
source share

timespec overflow is usually the culprit of weird timeouts.
Check out EINVAL:

 void timespec_add(struct timespec* a, struct timespec* b, struct timespec* out) { time_t sec = a->tv_sec + b->tv_sec; long nsec = a->tv_nsec + b->tv_nsec; sec += nsec / 1000000000L; nsec = nsec % 1000000000L; out->tv_sec = sec; out->tv_nsec = nsec; } 
+7
source share

The condition variable may falsely unlock. You need to check this in a loop and check the condition every time. You probably also need to update the timeout value.

I found the documentation for pthread_cond_timedwait here .

When using variables, the condition is always a Boolean predicate involving related variables with a wait condition, which is true if the flow should continue. fake wakeups from pthread_cond_timedwait () or pthread_cond_wait () functions may occur. Since returning from pthread_cond_timedwait () or pthread_cond_wait () does not mean anything about the value of this predicate, the predicate must be reevaluated with such a return.

+3
source share

As mentioned in the other answers mentioned, you should use absolute time. With C11 you can use timespec_get() .

 struct timespec time; timespec_get(&time, TIME_UTC); time.tv_sec += 5; pthread_cond_timedwait(&cond, &mutex, &time); 
0
source share

All Articles