Open main menu
Home
Random
Recent changes
Special pages
Community portal
Preferences
About Wikipedia
Disclaimers
Incubator escapee wiki
Search
User menu
Talk
Dark mode
Contributions
Create account
Log in
Editing
Monitor (synchronization)
(section)
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
===Condition variables=== The solution is to use '''condition variables'''. Conceptually, a condition variable is a queue of threads, associated with a mutex, on which a thread may wait for some condition to become true. Thus each condition variable {{mvar|c}} is associated with an [[assertion (computing)|assertion]] {{mvar|P<sub>c</sub>}}. While a thread is waiting on a condition variable, that thread is not considered to occupy the monitor, and so other threads may enter the monitor to change the monitor's state. In most types of monitors, these other threads may signal the condition variable {{mvar|c}} to indicate that assertion {{mvar|P<sub>c</sub>}} is true in the current state. Thus there are three main operations on condition variables: * <code>'''wait''' c, m</code>, where <code>''c''</code> is a condition variable and <code>m</code> is a [[lock (computer science)|mutex (lock)]] associated with the monitor. This operation is called by a thread that needs to wait until the assertion {{mvar|P<sub>c</sub>}} is true before proceeding. While the thread is waiting, it does not occupy the monitor. The function, and fundamental contract, of the "wait" operation, is to do the following steps: *# [[atomic operation|Atomically]]: *#: {{Ordered list|type=lower-alpha | release the mutex <code>''m''</code>, | move this thread from the "running" to <code>''c''</code>'s "wait-queue" (a.k.a. "sleep-queue") of threads, and | sleep this thread. (Context is synchronously yielded to another thread.)}} *# Once this thread is subsequently notified/signaled (see below) and resumed, then automatically re-acquire the mutex <code>''m''</code>. *:Steps 1a and 1b can occur in either order, with 1c usually occurring after them. While the thread is sleeping and in <code>''c''</code>'s wait-queue, the next [[program counter]] to be executed is at step 2, in the middle of the "wait" function/[[subroutine]]. Thus, the thread sleeps and later wakes up in the middle of the "wait" operation. *:The atomicity of the operations within step 1 is important to avoid race conditions that would be caused by a preemptive thread switch in-between them. One failure mode that could occur if these were not atomic is a ''missed wakeup'', in which the thread could be on <code>''c''</code>'s sleep-queue and have released the mutex, but a preemptive thread switch occurred before the thread went to sleep, and another thread called a signal operation (see below) on <code>''c''</code> moving the first thread back out of <code>''c''</code>'s queue. As soon as the first thread in question is switched back to, its program counter will be at step 1c, and it will sleep and be unable to be woken up again, violating the invariant that it should have been on <code>''c''</code>'s sleep-queue when it slept. Other race conditions depend on the ordering of steps 1a and 1b, and depend on where a context switch occurs. * <code>'''signal''' c</code>, also known as <code>'''notify''' c</code>, is called by a thread to indicate that the assertion {{mvar|P<sub>c</sub>}} is true. Depending on the type and implementation of the monitor, this moves one or more threads from <code>c</code>'s sleep-queue to the "ready queue", or another queue for it to be executed. It is usually considered a best practice to perform the "signal" operation before releasing mutex <code>''m''</code> that is associated with <code>''c''</code>, but as long as the code is properly designed for concurrency and depending on the threading implementation, it is often also acceptable to release the lock before signalling. Depending on the threading implementation, the ordering of this can have scheduling-priority ramifications. (Some authors{{who|date=March 2019}} instead advocate a preference for releasing the lock before signalling.) A threading implementation should document any special constraints on this ordering. * <code>'''broadcast''' c</code>, also known as <code>'''notifyAll''' c</code>, is a similar operation that wakes up all threads in c's wait-queue. This empties the wait-queue. Generally, when more than one predicate condition is associated with the same condition variable, the application will require '''broadcast''' instead of '''signal''' because a thread waiting for the wrong condition might be woken up and then immediately go back to sleep without waking up a thread waiting for the correct condition that just became true. Otherwise, if the predicate condition is one-to-one with the condition variable associated with it, then '''signal''' may be more efficient than '''broadcast'''. As a design rule, multiple condition variables can be associated with the same mutex, but not vice versa. (This is a [[multivalued function|one-to-many]] correspondence.) This is because the predicate {{mvar|P<sub>c</sub>}} is the same for all threads using the monitor and must be protected with mutual exclusion from all other threads that might cause the condition to be changed or that might read it while the thread in question causes it to be changed, but there may be different threads that want to wait for a different condition on the same variable requiring the same mutex to be used. In the producer-consumer example [[#Case_study:_classic_bounded_producer.2Fconsumer_problem|described above]], the queue must be protected by a unique mutex object, <code>''m''</code>. The "producer" threads will want to wait on a monitor using lock <code>''m''</code> and a condition variable <math>c_{full}</math> which blocks until the queue is non-full. The "consumer" threads will want to wait on a different monitor using the same mutex <code>''m''</code> but a different condition variable <math>c_{empty}</math> which blocks until the queue is non-empty. It would (usually) not make sense to have different mutexes for the same condition variable, but this classic example shows why it often certainly makes sense to have multiple condition variables using the same mutex. A mutex used by one or more condition variables (one or more monitors) may also be shared with code that does ''not'' use condition variables (and which simply acquires/releases it without any wait/signal operations), if those [[critical section]]s do not happen to require waiting for a certain condition on the concurrent data.
Edit summary
(Briefly describe your changes)
By publishing changes, you agree to the
Terms of Use
, and you irrevocably agree to release your contribution under the
CC BY-SA 4.0 License
and the
GFDL
. You agree that a hyperlink or URL is sufficient attribution under the Creative Commons license.
Cancel
Editing help
(opens in new window)