Originální popis anglicky:
pthread_cond_timedwait, pthread_cond_wait - wait on a condition
Návod, kniha: POSIX Programmer's Manual
#include <pthread.h>
int pthread_cond_timedwait(pthread_cond_t *restrict
cond,
pthread_mutex_t *restrict
mutex,
const struct timespec *restrict
abstime);
int pthread_cond_wait(pthread_cond_t *restrict
cond,
pthread_mutex_t *restrict
mutex);
The
pthread_cond_timedwait() and
pthread_cond_wait() functions
shall block on a condition variable. They shall be called with
mutex
locked by the calling thread or undefined behavior results.
These functions atomically release
mutex and cause the calling thread to
block on the condition variable
cond; atomically here means
"atomically with respect to access by another thread to the mutex and
then the condition variable". That is, if another thread is able to
acquire the mutex after the about-to-block thread has released it, then a
subsequent call to
pthread_cond_broadcast() or
pthread_cond_signal() in that thread shall behave as if it were issued
after the about-to-block thread has blocked.
Upon successful return, the mutex shall have been locked and shall be owned by
the calling thread.
When using condition variables there is always a Boolean predicate involving
shared variables associated with each condition wait that is true if the
thread should proceed. Spurious wakeups from the
pthread_cond_timedwait() or
pthread_cond_wait() functions may
occur. Since the return from
pthread_cond_timedwait() or
pthread_cond_wait() does not imply anything about the value of this
predicate, the predicate should be re-evaluated upon such return.
The effect of using more than one mutex for concurrent
pthread_cond_timedwait() or
pthread_cond_wait() operations on
the same condition variable is undefined; that is, a condition variable
becomes bound to a unique mutex when a thread waits on the condition variable,
and this (dynamic) binding shall end when the wait returns.
A condition wait (whether timed or not) is a cancellation point. When the
cancelability enable state of a thread is set to PTHREAD_CANCEL_DEFERRED, a
side effect of acting upon a cancellation request while in a condition wait is
that the mutex is (in effect) re-acquired before calling the first
cancellation cleanup handler. The effect is as if the thread were unblocked,
allowed to execute up to the point of returning from the call to
pthread_cond_timedwait() or
pthread_cond_wait(), but at that
point notices the cancellation request and instead of returning to the caller
of
pthread_cond_timedwait() or
pthread_cond_wait(), starts the
thread cancellation activities, which includes calling cancellation cleanup
handlers.
A thread that has been unblocked because it has been canceled while blocked in a
call to
pthread_cond_timedwait() or
pthread_cond_wait() shall
not consume any condition signal that may be directed concurrently at the
condition variable if there are other threads blocked on the condition
variable.
The
pthread_cond_timedwait() function shall be equivalent to
pthread_cond_wait(), except that an error is returned if the absolute
time specified by
abstime passes (that is, system time equals or
exceeds
abstime) before the condition
cond is signaled or
broadcasted, or if the absolute time specified by
abstime has already
been passed at the time of the call.
If the Clock Selection option is supported, the condition variable shall have a
clock attribute which specifies the clock that shall be used to measure the
time specified by the
abstime argument. When such timeouts occur,
pthread_cond_timedwait() shall nonetheless release and re-acquire the
mutex referenced by
mutex. The
pthread_cond_timedwait() function
is also a cancellation point.
If a signal is delivered to a thread waiting for a condition variable, upon
return from the signal handler the thread resumes waiting for the condition
variable as if it was not interrupted, or it shall return zero due to spurious
wakeup.
Except in the case of [ETIMEDOUT], all these error checks shall act as if they
were performed immediately at the beginning of processing for the function and
shall cause an error return, in effect, prior to modifying the state of the
mutex specified by
mutex or the condition variable specified by
cond.
Upon successful completion, a value of zero shall be returned; otherwise, an
error number shall be returned to indicate the error.
The
pthread_cond_timedwait() function shall fail if:
- ETIMEDOUT
- The time specified by abstime to
pthread_cond_timedwait() has passed.
The
pthread_cond_timedwait() and
pthread_cond_wait() functions may
fail if:
- EINVAL
- The value specified by cond, mutex, or
abstime is invalid.
- EINVAL
- Different mutexes were supplied for concurrent
pthread_cond_timedwait() or pthread_cond_wait() operations
on the same condition variable.
- EPERM
- The mutex was not owned by the current thread at the time
of the call.
These functions shall not return an error code of [EINTR].
The following sections are informative.
None.
None.
It is important to note that when
pthread_cond_wait() and
pthread_cond_timedwait() return without error, the associated predicate
may still be false. Similarly, when
pthread_cond_timedwait() returns
with the timeout error, the associated predicate may be true due to an
unavoidable race between the expiration of the timeout and the predicate state
change.
Some implementations, particularly on a multi-processor, may sometimes cause
multiple threads to wake up when the condition variable is signaled
simultaneously on different processors.
In general, whenever a condition wait returns, the thread has to re-evaluate the
predicate associated with the condition wait to determine whether it can
safely proceed, should wait again, or should declare a timeout. A return from
the wait does not imply that the associated predicate is either true or false.
It is thus recommended that a condition wait be enclosed in the equivalent of a
"while loop" that checks the predicate.
An absolute time measure was chosen for specifying the timeout parameter for two
reasons. First, a relative time measure can be easily implemented on top of a
function that specifies absolute time, but there is a race condition
associated with specifying an absolute timeout on top of a function that
specifies relative timeouts. For example, assume that
clock_gettime()
returns the current time and
cond_relative_timed_wait() uses relative
timeouts:
clock_gettime(CLOCK_REALTIME, &now)
reltime = sleep_til_this_absolute_time -now;
cond_relative_timed_wait(c, m, &reltime);
If the thread is preempted between the first statement and the last statement,
the thread blocks for too long. Blocking, however, is irrelevant if an
absolute timeout is used. An absolute timeout also need not be recomputed if
it is used multiple times in a loop, such as that enclosing a condition wait.
For cases when the system clock is advanced discontinuously by an operator, it
is expected that implementations process any timed wait expiring at an
intervening time as if that time had actually occurred.
A condition wait, whether timed or not, is a cancellation point. That is, the
functions
pthread_cond_wait() or
pthread_cond_timedwait() are
points where a pending (or concurrent) cancellation request is noticed. The
reason for this is that an indefinite wait is possible at these
points-whatever event is being waited for, even if the program is totally
correct, might never occur; for example, some input data being awaited might
never be sent. By making condition wait a cancellation point, the thread can
be canceled and perform its cancellation cleanup handler even though it may be
stuck in some indefinite wait.
A side effect of acting on a cancellation request while a thread is blocked on a
condition variable is to re-acquire the mutex before calling any of the
cancellation cleanup handlers. This is done in order to ensure that the
cancellation cleanup handler is executed in the same state as the critical
code that lies both before and after the call to the condition wait function.
This rule is also required when interfacing to POSIX threads from languages,
such as Ada or C++, which may choose to map cancellation onto a language
exception; this rule ensures that each exception handler guarding a critical
section can always safely depend upon the fact that the associated mutex has
already been locked regardless of exactly where within the critical section
the exception was raised. Without this rule, there would not be a uniform rule
that exception handlers could follow regarding the lock, and so coding would
become very cumbersome.
Therefore, since
some statement has to be made regarding the state of the
lock when a cancellation is delivered during a wait, a definition has been
chosen that makes application coding most convenient and error free.
When acting on a cancellation request while a thread is blocked on a condition
variable, the implementation is required to ensure that the thread does not
consume any condition signals directed at that condition variable if there are
any other threads waiting on that condition variable. This rule is specified
in order to avoid deadlock conditions that could occur if these two
independent requests (one acting on a thread and the other acting on the
condition variable) were not processed independently.
Mutexes are expected to be locked only for a few instructions. This practice is
almost automatically enforced by the desire of programmers to avoid long
serial regions of execution (which would reduce total effective parallelism).
When using mutexes and condition variables, one tries to ensure that the usual
case is to lock the mutex, access shared data, and unlock the mutex. Waiting
on a condition variable should be a relatively rare situation. For example,
when implementing a read-write lock, code that acquires a read-lock typically
needs only to increment the count of readers (under mutual-exclusion) and
return. The calling thread would actually wait on the condition variable only
when there is already an active writer. So the efficiency of a synchronization
operation is bounded by the cost of mutex lock/unlock and not by condition
wait. Note that in the usual case there is no context switch.
This is not to say that the efficiency of condition waiting is unimportant.
Since there needs to be at least one context switch per Ada rendezvous, the
efficiency of waiting on a condition variable is important. The cost of
waiting on a condition variable should be little more than the minimal cost
for a context switch plus the time to unlock and lock the mutex.
It had been suggested that the mutex acquisition and release be decoupled from
condition wait. This was rejected because it is the combined nature of the
operation that, in fact, facilitates realtime implementations. Those
implementations can atomically move a high-priority thread between the
condition variable and the mutex in a manner that is transparent to the
caller. This can prevent extra context switches and provide more deterministic
acquisition of a mutex when the waiting thread is signaled. Thus, fairness and
priority issues can be dealt with directly by the scheduling discipline.
Furthermore, the current condition wait operation matches existing practice.
Synchronization primitives that attempt to interfere with scheduling policy by
specifying an ordering rule are considered undesirable. Threads waiting on
mutexes and condition variables are selected to proceed in an order dependent
upon the scheduling policy rather than in some fixed order (for example, FIFO
or priority). Thus, the scheduling policy determines which thread(s) are
awakened and allowed to proceed.
The
pthread_cond_timedwait() function allows an application to give up
waiting for a particular condition after a given amount of time. An example of
its use follows:
(void) pthread_mutex_lock(&t.mn);
t.waiters++;
clock_gettime(CLOCK_REALTIME, &ts);
ts.tv_sec += 5;
rc = 0;
while (! mypredicate(&t) && rc == 0)
rc = pthread_cond_timedwait(&t.cond, &t.mn, &ts);
t.waiters--;
if (rc == 0) setmystate(&t);
(void) pthread_mutex_unlock(&t.mn);
By making the timeout parameter absolute, it does not need to be recomputed each
time the program checks its blocking predicate. If the timeout was relative,
it would have to be recomputed before each call. This would be especially
difficult since such code would need to take into account the possibility of
extra wakeups that result from extra broadcasts or signals on the condition
variable that occur before either the predicate is true or the timeout is due.
None.
pthread_cond_signal() ,
pthread_cond_broadcast() , the Base
Definitions volume of IEEE Std 1003.1-2001,
<pthread.h>
Portions of this text are reprinted and reproduced in electronic form from IEEE
Std 1003.1, 2003 Edition, Standard for Information Technology -- Portable
Operating System Interface (POSIX), The Open Group Base Specifications Issue
6, Copyright (C) 2001-2003 by the Institute of Electrical and Electronics
Engineers, Inc and The Open Group. In the event of any discrepancy between
this version and the original IEEE and The Open Group Standard, the original
IEEE and The Open Group Standard is the referee document. The original
Standard can be obtained online at http://www.opengroup.org/unix/online.html
.