#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
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.
For successful completion, the mutex lock associated with the condition variable must be locked before you call pthread_cond_timedwait().
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.
The value specified for the argument is not correct.
The mutex specified is not locked by the caller.
The wait timed out without being satisfied.
See Code disclaimer information for information pertaining to code examples.
#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
Top | Pthread APIs | APIs by category |