The threading.Condition
class in Python's threading
module provides a mechanism for threads to wait until they are notified. This is useful for scenarios where threads need to coordinate their actions and wait for certain conditions to be met before continuing execution.
Table of Contents
- Introduction
threading.Condition
Class Syntax- Examples
- Basic Usage
- Producer-Consumer Example
- Using Condition with Timeout
- Real-World Use Case
- Conclusion
Introduction
The threading.Condition
class is used to manage conditions and provide a way for threads to wait for certain conditions to be met. It allows one or more threads to wait until they are notified by another thread that a condition has been met. This is particularly useful for implementing advanced thread synchronization patterns like producer-consumer or reader-writer.
threading.Condition Class Syntax
Here is how you create and use a condition with the threading.Condition
class:
import threading
condition = threading.Condition()
Methods:
acquire()
: Acquire the underlying lock.release()
: Release the underlying lock.wait(timeout=None)
: Wait until notified or until a timeout occurs.notify(n=1)
: Notify one or more threads that are waiting on this condition.notify_all()
: Notify all threads that are waiting on this condition.
Example
import threading
condition = threading.Condition()
def wait_for_condition():
with condition:
print(f"{threading.current_thread().name} waiting for condition")
condition.wait()
print(f"{threading.current_thread().name} condition met")
def notify_condition():
with condition:
print(f"{threading.current_thread().name} notifying condition")
condition.notify()
# Create threads
wait_thread = threading.Thread(target=wait_for_condition, name="WaitThread")
notify_thread = threading.Thread(target=notify_condition, name="NotifyThread")
# Start threads
wait_thread.start()
notify_thread.start()
# Wait for threads to complete
wait_thread.join()
notify_thread.join()
Output:
WaitThread waiting for condition
NotifyThread notifying condition
WaitThread condition met
Examples
Basic Usage
Create and use a condition to synchronize threads.
Example
import threading
condition = threading.Condition()
def wait_for_condition():
with condition:
print(f"{threading.current_thread().name} waiting for condition")
condition.wait()
print(f"{threading.current_thread().name} condition met")
def notify_condition():
with condition:
print(f"{threading.current_thread().name} notifying condition")
condition.notify()
# Create threads
wait_thread = threading.Thread(target=wait_for_condition, name="WaitThread")
notify_thread = threading.Thread(target=notify_condition, name="NotifyThread")
# Start threads
wait_thread.start()
notify_thread.start()
# Wait for threads to complete
wait_thread.join()
notify_thread.join()
Producer-Consumer Example
Implement a producer-consumer pattern using a condition.
Example
import threading
import time
import random
buffer = []
buffer_size = 10
condition = threading.Condition()
def producer():
while True:
item = random.randint(1, 100)
with condition:
while len(buffer) == buffer_size:
condition.wait()
buffer.append(item)
print(f"Produced {item}")
condition.notify()
time.sleep(random.random())
def consumer():
while True:
with condition:
while not buffer:
condition.wait()
item = buffer.pop(0)
print(f"Consumed {item}")
condition.notify()
time.sleep(random.random())
producer_thread = threading.Thread(target=producer)
consumer_thread = threading.Thread(target=consumer)
producer_thread.start()
consumer_thread.start()
producer_thread.join()
consumer_thread.join()
Using Condition with Timeout
Use a condition with a timeout to wait for a condition to be met.
Example
import threading
condition = threading.Condition()
data_ready = False
def wait_for_data():
with condition:
print(f"{threading.current_thread().name} waiting for data")
result = condition.wait(timeout=5)
if result:
print(f"{threading.current_thread().name} data received")
else:
print(f"{threading.current_thread().name} timeout waiting for data")
def notify_data():
global data_ready
with condition:
data_ready = True
print(f"{threading.current_thread().name} notifying data")
condition.notify()
# Create threads
wait_thread = threading.Thread(target=wait_for_data, name="WaitThread")
notify_thread = threading.Thread(target=notify_data, name="NotifyThread")
# Start threads
wait_thread.start()
time.sleep(1) # Delay to ensure the wait thread starts waiting
notify_thread.start()
# Wait for threads to complete
wait_thread.join()
notify_thread.join()
Real-World Use Case
Thread-safe Queue
Implement a simple thread-safe queue using a condition.
Example
import threading
import time
class ThreadSafeQueue:
def __init__(self, max_size):
self.queue = []
self.max_size = max_size
self.condition = threading.Condition()
def put(self, item):
with self.condition:
while len(self.queue) == self.max_size:
self.condition.wait()
self.queue.append(item)
self.condition.notify()
def get(self):
with self.condition:
while not self.queue:
self.condition.wait()
item = self.queue.pop(0)
self.condition.notify()
return item
queue = ThreadSafeQueue(5)
def producer():
for i in range(10):
queue.put(i)
print(f"Produced {i}")
time.sleep(1)
def consumer():
for i in range(10):
item = queue.get()
print(f"Consumed {item}")
time.sleep(2)
producer_thread = threading.Thread(target=producer)
consumer_thread = threading.Thread(target=consumer)
producer_thread.start()
consumer_thread.start()
producer_thread.join()
consumer_thread.join()
Conclusion
The threading.Condition
class is used for managing complex synchronization scenarios in multithreaded programs. It allows threads to wait for certain conditions to be met before continuing execution, enabling the implementation of advanced thread synchronization patterns. Proper usage can significantly enhance the reliability and robustness of your concurrent applications.
Comments
Post a Comment
Leave Comment