Conditions are a wrapper around an underlying Lock
that provide wait/notify functionality. You need to acquire
a lock before you can release it - which wait
does under the hood. Notably once it gets re-awoken, it reacquires the lock. Thus mutual exclusion is ensured between acquiring and releasing, with wait
"yielding" control of the lock, if that makes sense.
Instead of doing the acquiring/releasing manually, just use the Condition
as a context manager:
def consumer(cond):
with cond:
cond.wait()
logging.debug('Resource is available to consumer')
If for whatever reason you're stuck on a version of python without context managers, this is equivalent to:
def consumer(cond):
try:
cond.acquire()
cond.wait()
finally:
cond.release()
logging.debug('Resource is available to consumer')
Often you want to make sure that only one consumer gets awoken, so the following idiom is frequently used:
with cond:
while some_queue.isEmpty():
cond.wait()
#get one from queue
Thus you could notify
any number of consumers and the extra ones just go immediately back to sleep once the Queue is empty.