GNU Info

Info Node: (python2.1-lib.info)Condition Objects

(python2.1-lib.info)Condition Objects


Next: Semaphore Objects Prev: RLock Objects Up: threading
Enter node , (file) or (file)node

Condition Objects
-----------------

A condition variable is always associated with some kind of lock; this
can be passed in or one will be created by default.  (Passing one in is
useful when several condition variables must share the same lock.)

A condition variable has `acquire()' and `release()' methods that call
the corresponding methods of the associated lock.  It also has a
`wait()' method, and `notify()' and `notifyAll()' methods.  These three
must only be called when the calling thread has acquired the lock.

The `wait()' method releases the lock, and then blocks until it is
awakened by a `notify()' or `notifyAll()' call for the same condition
variable in another thread.  Once awakened, it re-acquires the lock and
returns.  It is also possible to specify a timeout.

The `notify()' method wakes up one of the threads waiting for the
condition variable, if any are waiting.  The `notifyAll()' method wakes
up all threads waiting for the condition variable.

Note: the `notify()' and `notifyAll()' methods don't release the lock;
this means that the thread or threads awakened will not return from
their `wait()' call immediately, but only when the thread that called
`notify()' or `notifyAll()' finally relinquishes ownership of the lock.

Tip: the typical programming style using condition variables uses the
lock to synchronize access to some shared state; threads that are
interested in a particular change of state call `wait()' repeatedly
until they see the desired state, while threads that modify the state
call `notify()' or `notifyAll()' when they change the state in such a
way that it could possibly be a desired state for one of the waiters.
For example, the following code is a generic producer-consumer
situation with unlimited buffer capacity:

     # Consume one item
     cv.acquire()
     while not an_item_is_available():
         cv.wait()
     get_an_available_item()
     cv.release()
     
     # Produce one item
     cv.acquire()
     make_an_item_available()
     cv.notify()
     cv.release()

To choose between `notify()' and `notifyAll()', consider whether one
state change can be interesting for only one or several waiting
threads.  E.g. in a typical producer-consumer situation, adding one
item to the buffer only needs to wake up one consumer thread.

`Condition([lock])'
     If the LOCK argument is given and not `None', it must be a `Lock'
     or `RLock' object, and it is used as the underlying lock.
     Otherwise, a new `RLock' object is created and used as the
     underlying lock.

`acquire(*args)'
     Acquire the underlying lock.  This method calls the corresponding
     method on the underlying lock; the return value is whatever that
     method returns.

`release()'
     Release the underlying lock.  This method calls the corresponding
     method on the underlying lock; there is no return value.

`wait([timeout])'
     Wait until notified or until a timeout occurs.  This must only be
     called when the calling thread has acquired the lock.

     This method releases the underlying lock, and then blocks until it
     is awakened by a `notify()' or `notifyAll()' call for the same
     condition variable in another thread, or until the optional
     timeout occurs.  Once awakened or timed out, it re-acquires the
     lock and returns.

     When the TIMEOUT argument is present and not `None', it should be
     a floating point number specifying a timeout for the operation in
     seconds (or fractions thereof).

     When the underlying lock is an `RLock', it is not released using
     its `release()' method, since this may not actually unlock the
     lock when it was acquired multiple times recursively.  Instead, an
     internal interface of the `RLock' class is used, which really
     unlocks it even when it has been recursively acquired several
     times.  Another internal interface is then used to restore the
     recursion level when the lock is reacquired.

`notify()'
     Wake up a thread waiting on this condition, if any.  This must
     only be called when the calling thread has acquired the lock.

     This method wakes up one of the threads waiting for the condition
     variable, if any are waiting; it is a no-op if no threads are
     waiting.

     The current implementation wakes up exactly one thread, if any are
     waiting.  However, it's not safe to rely on this behavior.  A
     future, optimized implementation may occasionally wake up more
     than one thread.

     Note: the awakened thread does not actually return from its
     `wait()' call until it can reacquire the lock.  Since `notify()'
     does not release the lock, its caller should.

`notifyAll()'
     Wake up all threads waiting on this condition.  This method acts
     like `notify()', but wakes up all waiting threads instead of one.


automatically generated by info2www version 1.2.2.9