Sunday 20 December 2015

Python: Threads: Condition objects

Condition object provides a mechanism to release lock and notify threads that are waiting on this lock. A Condition object always associated with some kind of lock. The lock is part of condition object.

threading.Condition(lock=None)
You can pass Lock instance (or) RLock instance to this method. if lock argument is not given, then a new RLock object is created and used as the underlying lock.

Following are the methods provided by threading.Condition class.
Method
Description
acquire(*args)
Acquire the underlying lock.
release()
Release the underlying lock
wait(timeout=None)
Wait until notified or until a timeout occurs. This method should be called after thread acquire the lock, else RuntimeError is raised.

Timeout is a float number, specifies time in seconds.
wait_for(predicate, timeout=None)
Wait until a condition evaluates to True. ‘timeout’ represents the maximum time to wait.
notify(n=1)
By default, notifies (wake up) one thread waiting on this condition. Calling thread must acquire the lock before calling this method, else RuntimeError is raised. Base don value of n, this method wakes up at most n of the threads waiting for the condition variable
notify_all()
Notify all threads that are waiting on this condition. Calling thread must acquire the lock before calling this method, else RuntimeError is raised.

Following application implements simple producer and consumer application. producer produces the items, and consumer consumes the items produced by the producer

Basic scenarios to be considered in producer consumer problem.

1. Consumer can't consume the items, if the items are not produced by producer. So consumer must wait until the producer produces items. So consumer calls the wait method of the producer object.

2. Once the consumer consumes the items, he must notify the producer, so producer produce the items.

3. Producer must wait until the consumer consumes the items.

4. Once the producer produces the items, then he must tell the consumer, Please consume the items. So he must notify the consumer.


ProducerConsumer.py
import threading
import time

global item, flag
item=0
flag=True

def producer(cv):
 global item, flag
 with cv:
  while(True):
   if(flag==True):
    time.sleep(1)
    item += 1
    print("Produced item ", item)
    flag=False
    cv.notify()
   else:
    cv.wait()
 
def consumer(cv):
 global item, flag
 with cv:
  while(True):
   if(flag==False):
    print("Consumed item ", item)
    flag= True
    cv.notify()
   else:
    cv.wait()

condition = threading.Condition()
consumer = threading.Thread(name='consumer1', target=consumer, args=(condition,))
producer = threading.Thread(name='producer1', target=producer, args=(condition,))

consumer.start()
producer.start()

$ python3 ProducerConsumer.py 
Produced item  1
Consumed item  1
Produced item  2
Consumed item  2
Produced item  3
Consumed item  3
Produced item  4
Consumed item  4


Previous                                                 Next                                                 Home

No comments:

Post a Comment