pthread_cond_timedwait()--Timed Wait for Condition


  Syntax:
 #include <pthread.h>
 #include <time.h>
 int pthread_cond_timedwait(pthread_cond_t *cond,
                           pthread_mutex_t *mutex,
                           const struct timespec *abstime);   
  Service Program Name: QP0WPTHR

  Default Public Authority: *USE

  Threadsafe: Yes

  Signal Safe: No

The pthread_cond_timedwait() function blocks the calling thread, waiting for the condition specified by cond to be signaled or broadcast to.

When pthread_cond_timedwait() is called, the calling thread must have mutex locked. 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.

If the wait is satisfied or times out, or if the thread is canceled, before the thread is allowed to continue, the mutex is automatically acquired by the calling thread. If mutex is not currently locked, an EPERM error results. You should always associate only one mutex with a condition at a time. Using two different mutexes with the same condition at the same time could lead to unpredictable serialization in your application.

The time to wait is specified by the abstime parameter as an absolute system time at which the wait expires. If the current system clock time passes the absolute time specified before the condition is signaled, an ETIMEDOUT error results. After the wait begins, the wait time is not affected by changes to the system clock.

Although time is specified in seconds and nanoseconds, the system has approximately millisecond granularity. Due to scheduling and priorities, the amount of time you actually wait might be slightly more or less than the amount of time specified.

The current absolute system time can be retrieved as a timeval structure using the system clock interface gettimeofday(). The timeval structure can easily have a delta value added to it and be converted to a timespec structure. The MI time interfaces can be used to retrieve the current system time. The MI time also needs to be converted to a timespec structure before use by pthread_cond_timedwait() using the Qp0zConvertTime() interface.

This function is a cancellation point.

Note: For dependable use of condition variables, and to ensure that you do not lose wake-up operations on condition variables, your application should always use a Boolean predicate and a mutex with the condition variable.


Authorities and Locks

For successful completion, the mutex lock associated with the condition variable must be locked before you call pthread_cond_timedwait().


Parameters

cond
(Input) Address of the condition variable to wait for
mutex
(Input) Address of the locked mutex associated with the condition variable
abstime
(Input) Address of the absolute system time at which the wait expires

Return Value

0
pthread_cond_timedwait() was successful.
value
pthread_cond_timedwait() was not successful. value is set to indicate the error condition.

Error Conditions

If pthread_cond_timedwait() was not successful, the error condition returned usually indicates one of the following errors. Under some conditions, the value returned could indicate an error other than those listed here.

[EINVAL]

The value specified for the argument is not correct.

[EPERM]

The mutex specified is not locked by the caller.

[ETIMEDOUT]

The wait timed out without being satisfied.


Related Information


Example

Note: By using the code examples, you agree to the terms of the Code license and disclaimer information.

#define _MULTI_THREADED
#include <stdio.h>
#include <qp0z1170.h>
#include <time.h>
#include <pthread.h>
#include "check.h"

/* For safe condition variable usage, must use a boolean predicate and  */
/* a mutex with the condition.                                          */
int                 workToDo = 0;
pthread_cond_t      cond  = PTHREAD_COND_INITIALIZER;
pthread_mutex_t     mutex = PTHREAD_MUTEX_INITIALIZER;

#define NTHREADS                3
#define WAIT_TIME_SECONDS       15

void *threadfunc(void *parm)
{
  int               rc;
  struct timespec   ts;
  struct timeval    tp;

  rc = pthread_mutex_lock(&mutex);
  checkResults("pthread_mutex_lock()\n", rc);

  /* Usually worker threads will loop on these operations */
  while (1) {
    rc =  gettimeofday(&tp, NULL);
    checkResults("gettimeofday()\n", rc);

    /* Convert from timeval to timespec */
    ts.tv_sec  = tp.tv_sec;
    ts.tv_nsec = tp.tv_usec * 1000;
    ts.tv_sec += WAIT_TIME_SECONDS;

    while (!workToDo) {
      printf("Thread blocked\n");
      rc = pthread_cond_timedwait(&cond, &mutex, &ts);
      /* If the wait timed out, in this example, the work is complete, and   */
      /* the thread will end.                                                */
      /* In reality, a timeout must be accompanied by some sort of checking  */
      /* to see if the work is REALLY all complete. In the simple example    */
      /* we will just go belly up when we time out.                          */
      if (rc == ETIMEDOUT) {
        printf("Wait timed out!\n");
        rc = pthread_mutex_unlock(&mutex);
        checkResults("pthread_mutex_lock()\n", rc);
        pthread_exit(NULL);
      }
      checkResults("pthread_cond_timedwait()\n", rc);
    }

    printf("Thread consumes work here\n");
    workToDo = 0;
  }

  rc = pthread_mutex_unlock(&mutex);
  checkResults("pthread_mutex_lock()\n", rc);
  return NULL;
}

int main(int argc, char **argv)
{
  int                   rc=0;
  int                   i;
  pthread_t             threadid[NTHREADS];

  printf("Enter Testcase - %s\n", argv[0]);

  printf("Create %d threads\n", NTHREADS);
  for(i=0; i<NTHREADS; ++i) {
    rc = pthread_create(&threadid[i], NULL, threadfunc, NULL);
    checkResults("pthread_create()\n", rc);
  }

  rc = pthread_mutex_lock(&mutex);
  checkResults("pthread_mutex_lock()\n", rc);

  printf("One work item to give to a thread\n");
  workToDo = 1;
  rc = pthread_cond_signal(&cond);
  checkResults("pthread_cond_signal()\n", rc);

  rc = pthread_mutex_unlock(&mutex);
  checkResults("pthread_mutex_unlock()\n", rc);

  printf("Wait for threads and cleanup\n");
  for (i=0; i<NTHREADS; ++i) {
    rc = pthread_join(threadid[i], NULL);
    checkResults("pthread_join()\n", rc);
  }

  pthread_cond_destroy(&cond);
  pthread_mutex_destroy(&mutex);
  printf("Main completed\n");
  return 0;
}

Output:

Enter Testcase - QP0WTEST/TPCOT0
Create 3 threads
Thread blocked
One work item to give to a thread
Wait for threads and cleanup
Thread consumes work here
Thread blocked
Thread blocked
Thread blocked
Wait timed out!
Wait timed out!
Wait timed out!
Main completed

API introduced: V4R3

[ Back to top | Pthread APIs | APIs by category ]