COND_INIT(3C) Standard C Library Functions COND_INIT(3C)
NAME
cond_init, cond_wait, cond_timedwait, cond_reltimedwait, cond_signal,
cond_broadcast, cond_destroy - condition variables
SYNOPSIS
cc -mt [
flag... ]
file... [
library... ]
#include <thread.h>
#include <synch.h>
int cond_init(
cond_t *cvp,
int type,
void *arg);
int cond_wait(
cond_t *cvp,
mutex_t *mp);
int cond_timedwait(
cond_t *cvp,
mutex_t *mp,
timestruc_t *abstime);
int cond_reltimedwait(
cond_t *cvp,
mutex_t *mp,
timestruc_t *reltime);
int cond_signal(
cond_t *cvp);
int cond_broadcast(
cond_t *cvp);
int cond_destroy(
cond_t *cvp);
DESCRIPTION
Initialize
Condition variables and mutexes should be global. Condition variables
that are allocated in writable memory can synchronize threads among
processes if they are shared by the cooperating processes (see
mmap(2)) and are initialized for this purpose.
The scope of a condition variable is either intra-process or inter-
process. This is dependent upon whether the argument is passed
implicitly or explicitly to the initialization of that condition
variable. A condition variable does not need to be explicitly
initialized. A condition variable is initialized with all zeros, by
default, and its scope is set to within the calling process. For
inter-process synchronization, a condition variable must be
initialized once, and only once, before use.
A condition variable must not be simultaneously initialized by
multiple threads or re-initialized while in use by other threads.
Attributes of condition variables can be set to the default or
customized at initialization.
The
cond_init() function initializes the condition variable pointed
to by
cvp. A condition variable can have several different types of
behavior, specified by
type. No current type uses
arg although a
future type may specify additional behavior parameters with
arg. The
type argument can take one of the following values:
USYNC_THREAD The condition variable can synchronize threads only
in this process. This is the default.
USYNC_PROCESS The condition variable can synchronize threads in
this process and other processes. Only one process
should initialize the condition variable. The object
initialized with this attribute must be allocated in
memory shared between processes, either in System V
shared memory (see
shmop(2)) or in memory mapped to
a file (see
mmap(2)). It is illegal to initialize
the object this way and to not allocate it in such
shared memory.
Initializing condition variables can also be accomplished by
allocating in zeroed memory, in which case, a
type of
USYNC_THREAD is
assumed.
If default condition variable attributes are used, statically
allocated condition variables can be initialized by the macro
DEFAULTCV.
Default condition variable initialization (intra-process):
cond_t cvp;
cond_init(&cvp, 0, NULL); /*initialize condition variable
with default*/
or
cond_init(&cvp, USYNC_THREAD, NULL);
or
cond_t cond = DEFAULTCV;
Customized condition variable initialization (inter-process):
cond_init(&cvp, USYNC_PROCESS, NULL); /* initialize cv with
inter-process scope */
Condition Wait
The condition wait interface allows a thread to wait for a condition
and atomically release the associated mutex that it needs to hold to
check the condition. The thread waits for another thread to make the
condition true and that thread's resulting call to signal and wakeup
the waiting thread.
The
cond_wait() function atomically releases the mutex pointed to by
mp and causes the calling thread to block on the condition variable
pointed to by
cvp. The blocked thread may be awakened by
cond_signal(),
cond_broadcast(), or when interrupted by delivery of a
UNIX signal or a
fork().
The
cond_wait(),
cond_timedwait(), and
cond_reltimedwait() functions
always return with the mutex locked and owned by the calling thread
even when returning an error, except when the mutex has the
LOCK_ROBUST attribute and has been left irrecoverable by the mutex's
last owner. The
cond_wait(),
cond_timedwait(), and
cond_reltimedwait() functions return the appropriate error value if
they fail to internally reacquire the mutex.
Condition Signaling
A condition signal allows a thread to unblock a single thread waiting
on the condition variable, whereas a condition broadcast allows a
thread to unblock all threads waiting on the condition variable.
The
cond_signal() function unblocks one thread that is blocked on the
condition variable pointed to by
cvp.
The
cond_broadcast() function unblocks all threads that are blocked
on the condition variable pointed to by
cvp.
If no threads are blocked on the condition variable, then
cond_signal() and
cond_broadcast() have no effect.
The
cond_signal() or
cond_broadcast() functions can be called by a
thread whether or not it currently owns the mutex that threads
calling
cond_wait(),
cond_timedwait(), or
cond_reltimedwait() have
associated with the condition variable during their waits. If,
however, predictable scheduling behavior is required, then that mutex
should be locked by the thread prior to calling
cond_signal() or
cond_broadcast().
Destroy
The condition destroy functions destroy any state, but not the space,
associated with the condition variable.
The
cond_destroy() function destroys any state associated with the
condition variable pointed to by
cvp. The space for storing the
condition variable is not freed.
RETURN VALUES
Upon successful completion, these functions return
0. Otherwise, a
non-zero value is returned to indicate the error.
ERRORS
The
cond_timedwait() and
cond_reltimedwait() functions will fail if:
ETIME The time specified by
abstime or
reltime has passed.
The
cond_wait(),
cond_timedwait(), and
cond_reltimedwait() functions
will fail if:
EINTR Interrupted. The calling thread was awakened by the delivery
of a UNIX signal.
If the mutex pointed to by
mp is a robust mutex (initialized with the
LOCK_ROBUST attribute), the
cond_wait(),
cond_timedwait() and
cond_reltimedwait() functions will, under the specified conditions,
return the following error values. For complete information, see the
description of the
mutex_lock() function on the
mutex_init(3C) manual
page.
ENOTRECOVERABLE The mutex was protecting the state that has now
been left irrecoverable. The mutex has not been
acquired.
EOWNERDEAD The last owner of the mutex died while holding the
mutex, possibly leaving the state it was
protecting inconsistent. The mutex is now owned by
the caller.
These functions may fail if:
EFAULT The
cond,
attr,
cvp,
arg,
abstime, or
mutex argument points
to an illegal address.
EINVAL Invalid argument. For
cond_init(),
type is not a recognized
type. For
cond_timedwait(), the number of nanoseconds is
greater than or equal to 1,000,000,000.
EXAMPLES
Example 1: Use cond_wait() in a loop to test some condition.
The
cond_wait() function is normally used in a loop testing some
condition, as follows:
(void) mutex_lock(mp);
while (cond == FALSE) {
(void) cond_wait(cvp, mp);
}
(void) mutex_unlock(mp);
Example 2: Use cond_timedwait() in a loop to test some condition.
The
cond_timedwait() function is normally used in a loop testing some
condition. It uses an absolute timeout value as follows:
timestruc_t to;
...
(void) mutex_lock(mp);
to.tv_sec = time(NULL) + TIMEOUT;
to.tv_nsec = 0;
while (cond == FALSE) {
err = cond_timedwait(cvp, mp, &to);
if (err == ETIME) {
/* timeout, do something */
break;
}
}
(void) mutex_unlock(mp);
Example 3: Use cond_reltimedwait() in a loop to test some condition.
The
cond_reltimedwait() function is normally used in a loop testing
in some condition. It uses a relative timeout value as follows:
timestruc_t to;
...
(void) mutex_lock(mp);
while (cond == FALSE) {
to.tv_sec = TIMEOUT;
to.tv_nsec = 0;
err = cond_reltimedwait(cvp, mp, &to);
if (err == ETIME) {
/* timeout, do something */
break;
}
}
(void) mutex_unlock(mp);
ATTRIBUTES
See
attributes(7) for descriptions of the following attributes:
+---------------+-----------------+
|ATTRIBUTE TYPE | ATTRIBUTE VALUE |
+---------------+-----------------+
|MT-Level | MT-Safe |
+---------------+-----------------+
SEE ALSO
fork(2),
mmap(2),
setitimer(2),
shmop(2),
mutex_init(3C),
signal(3C),
attributes(7),
condition(7),
mutex(7),
standards(7)NOTES
If more than one thread is blocked on a condition variable, the order
in which threads are unblocked is determined by the scheduling
policy. When each thread, unblocked as a result of a
cond_signal() or
cond_broadcast(), returns from its call to
cond_wait() or
cond_timedwait() , the thread owns the mutex with which it called
cond_wait(),
cond_timedwait(), or
cond_reltimedwait(). The thread(s)
that are unblocked compete for the mutex according to the scheduling
policy and as if each had called
mutex_lock(3C).
When
cond_wait() returns the value of the condition is indeterminate
and must be reevaluated.
The
cond_timedwait() and
cond_reltimedwait() functions are similar to
cond_wait(), except that the calling thread will not wait for the
condition to become true past the absolute time specified by
abstime or the relative time specified by
reltime. Note that
cond_timedwait() or
cond_reltimedwait() might continue to block as it tries to
reacquire the mutex pointed to by
mp, which may be locked by another
thread. If either
cond_timedwait() or
cond_reltimedwait() returns
because of a timeout, it returns the error value
ETIME.
September 15, 2024 COND_INIT(3C)