Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 126aef7

Browse files
committed
Issue #8799: Fix and improve the threading.Condition documentation.
1 parent 88b957a commit 126aef7

2 files changed

Lines changed: 64 additions & 54 deletions

File tree

Doc/library/threading.rst

Lines changed: 59 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -503,62 +503,73 @@ Condition Objects
503503
-----------------
504504

505505
A condition variable is always associated with some kind of lock; this can be
506-
passed in or one will be created by default. (Passing one in is useful when
507-
several condition variables must share the same lock.)
508-
509-
A condition variable has :meth:`acquire` and :meth:`release` methods that call
510-
the corresponding methods of the associated lock. It also has a :meth:`wait`
511-
method, and :meth:`notify` and :meth:`notify_all` methods. These three must only
512-
be called when the calling thread has acquired the lock, otherwise a
513-
:exc:`RuntimeError` is raised.
514-
515-
The :meth:`wait` method releases the lock, and then blocks until it is awakened
516-
by a :meth:`notify` or :meth:`notify_all` call for the same condition variable in
517-
another thread. Once awakened, it re-acquires the lock and returns. It is also
518-
possible to specify a timeout.
519-
520-
The :meth:`notify` method wakes up one of the threads waiting for the condition
521-
variable, if any are waiting. The :meth:`notify_all` method wakes up all threads
522-
waiting for the condition variable.
523-
524-
Note: the :meth:`notify` and :meth:`notify_all` methods don't release the lock;
525-
this means that the thread or threads awakened will not return from their
526-
:meth:`wait` call immediately, but only when the thread that called
527-
:meth:`notify` or :meth:`notify_all` finally relinquishes ownership of the lock.
528-
529-
Tip: the typical programming style using condition variables uses the lock to
506+
passed in or one will be created by default. Passing one in is useful when
507+
several condition variables must share the same lock. The lock is part of
508+
the condition object: you don't have to track it separately.
509+
510+
A condition variable obeys the :term:`context manager` protocol: using the
511+
``with`` statement acquires the associated lock for the duration of the
512+
enclosed block. The :meth:`~Condition.acquire` and :meth:`~Condition.release`
513+
methods also call the corresponding methods of the associated lock.
514+
515+
Other methods must be called with the associated lock held. The
516+
:meth:`~Condition.wait` method releases the lock, and then blocks until
517+
another thread awakens it by calling :meth:`~Condition.notify` or
518+
:meth:`~Condition.notify_all`. Once awakened, :meth:`~Condition.wait`
519+
re-acquires the lock and returns. It is also possible to specify a timeout.
520+
521+
The :meth:`~Condition.notify` method wakes up one of the threads waiting for
522+
the condition variable, if any are waiting. The :meth:`~Condition.notify_all`
523+
method wakes up all threads waiting for the condition variable.
524+
525+
Note: the :meth:`~Condition.notify` and :meth:`~Condition.notify_all` methods
526+
don't release the lock; this means that the thread or threads awakened will
527+
not return from their :meth:`~Condition.wait` call immediately, but only when
528+
the thread that called :meth:`~Condition.notify` or :meth:`~Condition.notify_all`
529+
finally relinquishes ownership of the lock.
530+
531+
532+
Usage
533+
^^^^^
534+
535+
The typical programming style using condition variables uses the lock to
530536
synchronize access to some shared state; threads that are interested in a
531-
particular change of state call :meth:`wait` repeatedly until they see the
532-
desired state, while threads that modify the state call :meth:`notify` or
533-
:meth:`notify_all` when they change the state in such a way that it could
534-
possibly be a desired state for one of the waiters. For example, the following
535-
code is a generic producer-consumer situation with unlimited buffer capacity::
537+
particular change of state call :meth:`~Condition.wait` repeatedly until they
538+
see the desired state, while threads that modify the state call
539+
:meth:`~Condition.notify` or :meth:`~Condition.notify_all` when they change
540+
the state in such a way that it could possibly be a desired state for one
541+
of the waiters. For example, the following code is a generic
542+
producer-consumer situation with unlimited buffer capacity::
536543

537544
# Consume one item
538-
cv.acquire()
539-
while not an_item_is_available():
540-
cv.wait()
541-
get_an_available_item()
542-
cv.release()
545+
with cv:
546+
while not an_item_is_available():
547+
cv.wait()
548+
get_an_available_item()
543549

544550
# Produce one item
545-
cv.acquire()
546-
make_an_item_available()
547-
cv.notify()
548-
cv.release()
551+
with cv:
552+
make_an_item_available()
553+
554+
The ``while`` loop checking for the application's condition is necessary
555+
because :meth:`~Condition.wait` can return after an arbitrary long time,
556+
and other threads may have exhausted the available items in between. This
557+
is inherent to multi-threaded programming. The :meth:`~Condition.wait_for`
558+
method can be used to automate the condition checking::
559+
560+
# Consume an item
561+
with cv:
562+
cv.wait_for(an_item_is_available)
563+
get_an_available_item()
549564

550-
To choose between :meth:`notify` and :meth:`notify_all`, consider whether one
551-
state change can be interesting for only one or several waiting threads. E.g.
552-
in a typical producer-consumer situation, adding one item to the buffer only
553-
needs to wake up one consumer thread.
565+
To choose between :meth:`~Condition.notify` and :meth:`~Condition.notify_all`,
566+
consider whether one state change can be interesting for only one or several
567+
waiting threads. E.g. in a typical producer-consumer situation, adding one
568+
item to the buffer only needs to wake up one consumer thread.
554569

555-
Note: Condition variables can be, depending on the implementation, subject
556-
to both spurious wakeups (when :meth:`wait` returns without a :meth:`notify`
557-
call) and stolen wakeups (when another thread acquires the lock before the
558-
awoken thread.) For this reason, it is always necessary to verify the state
559-
the thread is waiting for when :meth:`wait` returns and optionally repeat
560-
the call as often as necessary.
561570

571+
Interface
572+
^^^^^^^^^
562573

563574
.. class:: Condition(lock=None)
564575

@@ -626,12 +637,6 @@ the call as often as necessary.
626637
held when called and is re-aquired on return. The predicate is evaluated
627638
with the lock held.
628639

629-
Using this method, the consumer example above can be written thus::
630-
631-
with cv:
632-
cv.wait_for(an_item_is_available)
633-
get_an_available_item()
634-
635640
.. versionadded:: 3.2
636641

637642
.. method:: notify(n=1)

Misc/NEWS

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,11 @@ Build
138138
- Issue #14359: Only use O_CLOEXEC in _posixmodule.c if it is defined.
139139
Based on patch from Hervé Coatanhay.
140140

141+
Documentation
142+
-------------
143+
144+
- Issue #8799: Fix and improve the threading.Condition documentation.
145+
141146

142147
What's New in Python 3.2.3 release candidate 2?
143148
===============================================

0 commit comments

Comments
 (0)