mirror of https://github.com/mkerrisk/man-pages
336 lines
14 KiB
Plaintext
336 lines
14 KiB
Plaintext
.\" Copyright (c) 2001-2003 The Open Group, All Rights Reserved
|
|
.TH "PTHREAD_COND_TIMEDWAIT" P 2003 "IEEE/The Open Group" "POSIX Programmer's Manual"
|
|
.\" pthread_cond_timedwait
|
|
.SH NAME
|
|
pthread_cond_timedwait, pthread_cond_wait \- wait on a condition
|
|
.SH SYNOPSIS
|
|
.LP
|
|
\fB#include <pthread.h>
|
|
.br
|
|
.sp
|
|
int pthread_cond_timedwait(pthread_cond_t *restrict\fP \fIcond\fP\fB,
|
|
.br
|
|
\ \ \ \ \ \ pthread_mutex_t *restrict\fP \fImutex\fP\fB,
|
|
.br
|
|
\ \ \ \ \ \ const struct timespec *restrict\fP \fIabstime\fP\fB);
|
|
.br
|
|
int pthread_cond_wait(pthread_cond_t *restrict\fP \fIcond\fP\fB,
|
|
.br
|
|
\ \ \ \ \ \ pthread_mutex_t *restrict\fP \fImutex\fP\fB); \fP
|
|
\fB
|
|
.br
|
|
\fP
|
|
.SH DESCRIPTION
|
|
.LP
|
|
The \fIpthread_cond_timedwait\fP() and \fIpthread_cond_wait\fP() functions
|
|
shall block on a condition variable. They shall be
|
|
called with \fImutex\fP locked by the calling thread or undefined
|
|
behavior results.
|
|
.LP
|
|
These functions atomically release \fImutex\fP and cause the calling
|
|
thread to block on the condition variable \fIcond\fP;
|
|
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 \fIpthread_cond_broadcast\fP()
|
|
or \fIpthread_cond_signal\fP() in that thread shall behave as if it
|
|
were issued after the
|
|
about-to-block thread has blocked.
|
|
.LP
|
|
Upon successful return, the mutex shall have been locked and shall
|
|
be owned by the calling thread.
|
|
.LP
|
|
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 \fIpthread_cond_timedwait\fP() or
|
|
\fIpthread_cond_wait\fP() functions may occur. Since the return from
|
|
\fIpthread_cond_timedwait\fP() or \fIpthread_cond_wait\fP()
|
|
does not imply anything about the value of this predicate, the predicate
|
|
should be re-evaluated upon such return.
|
|
.LP
|
|
The effect of using more than one mutex for concurrent \fIpthread_cond_timedwait\fP()
|
|
or \fIpthread_cond_wait\fP() 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.
|
|
.LP
|
|
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 \fIpthread_cond_timedwait\fP()
|
|
or \fIpthread_cond_wait\fP(), but at that
|
|
point notices the cancellation request and instead of returning to
|
|
the caller of \fIpthread_cond_timedwait\fP() or
|
|
\fIpthread_cond_wait\fP(), starts the thread cancellation activities,
|
|
which includes calling cancellation cleanup handlers.
|
|
.LP
|
|
A thread that has been unblocked because it has been canceled while
|
|
blocked in a call to \fIpthread_cond_timedwait\fP() or
|
|
\fIpthread_cond_wait\fP() 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.
|
|
.LP
|
|
The \fIpthread_cond_timedwait\fP() function shall be equivalent to
|
|
\fIpthread_cond_wait\fP(), except that an error is returned
|
|
if the absolute time specified by \fIabstime\fP passes (that is, system
|
|
time equals or exceeds \fIabstime\fP) before the
|
|
condition \fIcond\fP is signaled or broadcasted, or if the absolute
|
|
time specified by \fIabstime\fP has already been passed at
|
|
the time of the call.
|
|
.LP
|
|
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 \fIabstime\fP argument.
|
|
When such timeouts occur, \fIpthread_cond_timedwait\fP() shall nonetheless
|
|
release and re-acquire the mutex referenced by
|
|
\fImutex\fP. The \fIpthread_cond_timedwait\fP() function is also a
|
|
cancellation point.
|
|
.LP
|
|
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.
|
|
.SH RETURN VALUE
|
|
.LP
|
|
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
|
|
\fImutex\fP or the condition variable specified by \fIcond\fP.
|
|
.LP
|
|
Upon successful completion, a value of zero shall be returned; otherwise,
|
|
an error number shall be returned to indicate the
|
|
error.
|
|
.SH ERRORS
|
|
.LP
|
|
The \fIpthread_cond_timedwait\fP() function shall fail if:
|
|
.TP 7
|
|
.B ETIMEDOUT
|
|
The time specified by \fIabstime\fP to \fIpthread_cond_timedwait\fP()
|
|
has passed.
|
|
.sp
|
|
.LP
|
|
The \fIpthread_cond_timedwait\fP() and \fIpthread_cond_wait\fP() functions
|
|
may fail if:
|
|
.TP 7
|
|
.B EINVAL
|
|
The value specified by \fIcond\fP, \fImutex\fP, or \fIabstime\fP is
|
|
invalid.
|
|
.TP 7
|
|
.B EINVAL
|
|
Different mutexes were supplied for concurrent \fIpthread_cond_timedwait\fP()
|
|
or \fIpthread_cond_wait\fP() operations on the
|
|
same condition variable.
|
|
.TP 7
|
|
.B EPERM
|
|
The mutex was not owned by the current thread at the time of the call.
|
|
.sp
|
|
.LP
|
|
These functions shall not return an error code of [EINTR].
|
|
.LP
|
|
\fIThe following sections are informative.\fP
|
|
.SH EXAMPLES
|
|
.LP
|
|
None.
|
|
.SH APPLICATION USAGE
|
|
.LP
|
|
None.
|
|
.SH RATIONALE
|
|
.SS Condition Wait Semantics
|
|
.LP
|
|
It is important to note that when \fIpthread_cond_wait\fP() and \fIpthread_cond_timedwait\fP()
|
|
return without error, the
|
|
associated predicate may still be false. Similarly, when \fIpthread_cond_timedwait\fP()
|
|
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.
|
|
.LP
|
|
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.
|
|
.LP
|
|
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.
|
|
.LP
|
|
It is thus recommended that a condition wait be enclosed in the equivalent
|
|
of a "while loop" that checks the predicate.
|
|
.SS Timed Wait Semantics
|
|
.LP
|
|
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 \fIclock_gettime\fP() returns the current
|
|
time and \fIcond_relative_timed_wait\fP() uses
|
|
relative timeouts:
|
|
.sp
|
|
.RS
|
|
.nf
|
|
|
|
\fBclock_gettime(CLOCK_REALTIME, &now)
|
|
reltime = sleep_til_this_absolute_time -now;
|
|
cond_relative_timed_wait(c, m, &reltime);
|
|
\fP
|
|
.fi
|
|
.RE
|
|
.LP
|
|
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.
|
|
.LP
|
|
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.
|
|
.SS Cancellation and Condition Wait
|
|
.LP
|
|
A condition wait, whether timed or not, is a cancellation point. That
|
|
is, the functions \fIpthread_cond_wait\fP() or
|
|
\fIpthread_cond_timedwait\fP() 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.
|
|
.LP
|
|
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.
|
|
.LP
|
|
Therefore, since \fIsome\fP 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.
|
|
.LP
|
|
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.
|
|
.SS Performance of Mutexes and Condition Variables
|
|
.LP
|
|
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).
|
|
.LP
|
|
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.
|
|
.LP
|
|
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.
|
|
.SS Features of Mutexes and Condition Variables
|
|
.LP
|
|
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.
|
|
.SS Scheduling Behavior of Mutexes and Condition Variables
|
|
.LP
|
|
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.
|
|
.SS Timed Condition Wait
|
|
.LP
|
|
The \fIpthread_cond_timedwait\fP() function allows an application
|
|
to give up waiting for a particular condition after a given
|
|
amount of time. An example of its use follows:
|
|
.sp
|
|
.RS
|
|
.nf
|
|
|
|
\fB(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);
|
|
\fP
|
|
.fi
|
|
.RE
|
|
.LP
|
|
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.
|
|
.SH FUTURE DIRECTIONS
|
|
.LP
|
|
None.
|
|
.SH SEE ALSO
|
|
.LP
|
|
\fIpthread_cond_signal\fP() , \fIpthread_cond_broadcast\fP() , the
|
|
Base Definitions volume of IEEE\ Std\ 1003.1-2001,
|
|
\fI<pthread.h>\fP
|
|
.SH COPYRIGHT
|
|
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 .
|