PTHREAD_COND_BROADCAST(3)  POSIX Programmer's Manual PTHREAD_COND_BROADCAST(3)



PROLOG
       This manual page is part of the POSIX Programmer's Manual.  The OS
       implementation of this interface may differ (consult the corresponding
       OS manual page for details of OS behavior), or the interface may not be
       implemented on OS.

NAME
       pthread_cond_broadcast, pthread_cond_signal -- broadcast or signal a
       condition

SYNOPSIS
       #include <pthread.h>

       int pthread_cond_broadcast(pthread_cond_t *cond);
       int pthread_cond_signal(pthread_cond_t *cond);

DESCRIPTION
       These functions shall unblock threads blocked on a condition variable.

       The pthread__cond__broadcast() function shall unblock all threads
       currently blocked on the specified condition variable cond.

       The pthread__cond__signal() function shall unblock at least one of the
       threads that are blocked on the specified condition variable cond (if
       any threads are blocked on cond).

       If more than one thread is blocked on a condition variable, the
       scheduling policy shall determine the order in which threads are
       unblocked. When each thread unblocked as a result of a
       pthread__cond__broadcast() or pthread__cond__signal() returns from its call
       to pthread__cond__wait() or pthread__cond__timedwait(), the thread shall
       own the mutex with which it called pthread__cond__wait() or
       pthread__cond__timedwait().  The thread(s) that are unblocked shall
       contend for the mutex according to the scheduling policy (if
       applicable), and as if each had called pthread__mutex__lock().

       The pthread__cond__broadcast() or pthread__cond__signal() functions may be
       called by a thread whether or not it currently owns the mutex that
       threads calling pthread__cond__wait() or pthread__cond__timedwait() have
       associated with the condition variable during their waits; however, if
       predictable scheduling behavior is required, then that mutex shall be
       locked by the thread calling pthread__cond__broadcast() or
       pthread__cond__signal().

       The pthread__cond__broadcast() and pthread__cond__signal() functions shall
       have no effect if there are no threads currently blocked on cond.

       The behavior is undefined if the value specified by the cond argument
       to pthread__cond__broadcast() or pthread__cond__signal() does not refer to
       an initialized condition variable.

RETURN VALUE
       If successful, the pthread__cond__broadcast() and pthread__cond__signal()
       functions shall return zero; otherwise, an error number shall be
       returned to indicate the error.

ERRORS
       These functions shall not return an error code of [EINTR].

       The following sections are informative.

EXAMPLES
       None.

APPLICATION USAGE
       The pthread__cond__broadcast() function is used whenever the shared-
       variable state has been changed in a way that more than one thread can
       proceed with its task. Consider a single producer/multiple consumer
       problem, where the producer can insert multiple items on a list that is
       accessed one item at a time by the consumers. By calling the
       pthread__cond__broadcast() function, the producer would notify all
       consumers that might be waiting, and thereby the application would
       receive more throughput on a multi-processor. In addition,
       pthread__cond__broadcast() makes it easier to implement a read-write
       lock. The pthread__cond__broadcast() function is needed in order to wake
       up all waiting readers when a writer releases its lock. Finally, the
       two-phase commit algorithm can use this broadcast function to notify
       all clients of an impending transaction commit.

       It is not safe to use the pthread__cond__signal() function in a signal
       handler that is invoked asynchronously. Even if it were safe, there
       would still be a race between the test of the Boolean
       pthread__cond__wait() that could not be efficiently eliminated.

       Mutexes and condition variables are thus not suitable for releasing a
       waiting thread by signaling from code running in a signal handler.

RATIONALE
       If an implementation detects that the value specified by the cond
       argument to pthread__cond__broadcast() or pthread__cond__signal() does not
       refer to an initialized condition variable, it is recommended that the
       function should fail and report an [EINVAL] error.

   Multiple Awakenings by Condition Signal
       On a multi-processor, it may be impossible for an implementation of
       pthread__cond__signal() to avoid the unblocking of more than one thread
       blocked on a condition variable. For example, consider the following
       partial implementation of pthread__cond__wait() and
       pthread__cond__signal(), executed by two threads in the order given. One
       thread is trying to wait on the condition variable, another is
       concurrently executing pthread__cond__signal(), while a third thread is
       already waiting.


           pthread_cond_wait(mutex, cond):
               value = cond->value; /* 1 */
               pthread_mutex_unlock(mutex); /* 2 */
               pthread_mutex_lock(cond->mutex); /* 10 */
               if (value == cond->value) { /* 11 */
                   me->next_cond = cond->waiter;
                   cond->waiter = me;
                   pthread_mutex_unlock(cond->mutex);
                   unable_to_run(me);
               } else
                   pthread_mutex_unlock(cond->mutex); /* 12 */
               pthread_mutex_lock(mutex); /* 13 */

           pthread_cond_signal(cond):
               pthread_mutex_lock(cond->mutex); /* 3 */
               cond->value++; /* 4 */
               if (cond->waiter) { /* 5 */
                   sleeper = cond->waiter; /* 6 */
                   cond->waiter = sleeper->next_cond; /* 7 */
                   able_to_run(sleeper); /* 8 */
               }
               pthread_mutex_unlock(cond->mutex); /* 9 */

       The effect is that more than one thread can return from its call to
       pthread__cond__wait() or pthread__cond__timedwait() as a result of one call
       to pthread__cond__signal().  This effect is called ``spurious wakeup''.
       Note that the situation is self-correcting in that the number of
       threads that are so awakened is finite; for example, the next thread to
       call pthread__cond__wait() after the sequence of events above blocks.

       While this problem could be resolved, the loss of efficiency for a
       fringe condition that occurs only rarely is unacceptable, especially
       given that one has to check the predicate associated with a condition
       variable anyway. Correcting this problem would unnecessarily reduce the
       degree of concurrency in this basic building block for all higher-level
       synchronization operations.

       An added benefit of allowing spurious wakeups is that applications are
       forced to code a predicate-testing-loop around the condition wait.
       This also makes the application tolerate superfluous condition
       broadcasts or signals on the same condition variable that may be coded
       in some other part of the application. The resulting applications are
       thus more robust. Therefore, POSIX.1-2008 explicitly documents that
       spurious wakeups may occur.

FUTURE DIRECTIONS
       None.

SEE ALSO
       pthread__cond__destroy(), pthread__cond__timedwait()

       The Base Definitions volume of POSIX.1-2017, Section 4.12, Memory
       Synchronization, <pthread.h>

COPYRIGHT
       Portions of this text are reprinted and reproduced in electronic form
       from IEEE Std 1003.1-2017, Standard for Information Technology --
       Portable Operating System Interface (POSIX), The Open Group Base
       Specifications Issue 7, 2018 Edition, Copyright (C) 2018 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 .

       Any typographical or formatting errors that appear in this page are
       most likely to have been introduced during the conversion of the source
       files to man page format. To report such errors, see
       https://www.kernel.org/doc/man-pages/reporting_bugs.html .



IEEE/The Open Group                  2017            PTHREAD_COND_BROADCAST(3)
