Free cookie consent management tool by TermsFeed The wait() method of the Condition class in Python | Pythontic.com

The wait() method of the Condition class in Python

Overview:

  • The wait() method blocks when the predicate it is waiting for is currently False. To wait on a condition variable the underlying lock must be acquired by the calling thread.
  • When the predicate becomes True the waiting thread is notified of by another thread - the wait() releases the lock and proceeds with the work. Typically, doing some work makes the predicate to become False again.
  • Waiting when a predicate is False and waking up from the waiting upon the predicate becoming True continues in a while loop. If a terminal condition is handled then the while loop breaks when the terminal condition becomes True.
  • When no lock object is specified for the Condition variable, Python uses an RLock object as the underlying lock for the Condition.
  • The example Python program that uses a condition variable in the introduction notifies the waiting thread(s) whenever there is an element available in the list for consumption. In the example below, the producer thread notifies only upon the deque becoming full.

Example:

# Example Python program that wakes up a consumer thread 
# that waits for a notification from a producer thread
# using a condition variable.

import collections as coll
import threading as th
import time

# The double ended queue whose maximum length is 5
objects     = coll.deque(maxlen = 5)
obj_count     = 0 

# Target function for the producer thread
def produceObjs(cvar):
    global objects
    global obj_count
    try:
        while(True):
            # Keep filling
            cvar.acquire()
            if(obj_count <= 0):
                # Fill the deque in one go
                for i in range(1, objects.maxlen+1):
                    objects.append("obj:%d"%i)
                    obj_count += 1
            if(obj_count == objects.maxlen):
                print("Producer:Notifying")
                cvar.notify()
                cvar.release()
            time.sleep(2)
    finally:
        cvar.release()

# Target function for the consumer thread
def consumeObjs(cvar): 
    # Keep consuming    
    global obj_count
    try:
        while(True):
            cvar.acquire()
            cvar.wait()
            print("Consumer:Post-wait")
            for obj in objects:
                print(obj)
            objects.clear()
            obj_count = 0

            cvar.release()
    finally:
        cvar.release()

# Create the underlying lock
lockObject = th.Lock()

# Create the condition variable
conditionObject = th.Condition(lockObject)

# Create the producer and consumer threads
producerThread = th.Thread(target = produceObjs, args=(conditionObject,))
consumerThread = th.Thread(target = consumeObjs, args=(conditionObject,))

# Starting the consumer thread first...
# (Not to miss any notification from the producer)
consumerThread.start()
producerThread.start()

# Wait for the producer and consumer threads to finish
# (There is no terminal condition specified/handled...
#  hence the threads and the parent program to run till 
#  stopped manually or the resources are deplete)
producerThread.join()
consumerThread.join()

Output:

Producer:Notifying
Consumer:Post-wait
obj:1
obj:2
obj:3
obj:4
obj:5

 

 


Copyright 2025 © pythontic.com