I am trying to implement Producer consumer scenario in Python... The producer is supposed to cease lock variable if the queue is full and release it if it is not full... I am using the lock variable in loop
def run(self):
#mutexProducer.acquire()
#Entering Critical section
#print self.queue.qsize()
while True:
customer=Customer()
self.mutex.acquire()# acquire condition variable to see if queue is full
if self.queue.full():
print "Queue is full : Cant Enter Critical Section"
#print "Customer %d is discarded" %(customer.id)
elif not self.queue.full() :
print "i am here"
print self.mutex.release()
self.mutex.acquire()
#Critical Section
self.queue.put(customer)#pushing Customer to queue
print "Customer %d Enters the Queue with %d service " %(customer.id,customer.serviceTime)
#critical Section
self.mutex.release()
Does my code lock multiple instances over and over again?? The reason i am asking is i am new to threads and After queue is full, The producer stops creating any process(customer in my case)
I added some notes on your code, which has some problems:
def run(self):
while True:
customer=Customer()
self.mutex.acquire()
if self.queue.full():
print "Queue is full : Cant Enter Critical Section"
# NOTE 1: you have to release mutex here: self.mutex.release()
elif not self.queue.full():
# NOTE 2: other threads can enter after releasing the lock
print self.mutex.release()
self.mutex.acquire()
#Critical Section
self.queue.put(customer)
print "Customer %d Enters the Queue with %d service " %(
customer.id,customer.serviceTime
)
self.mutex.release()
Alternative to NOTE 1 (but same motives):
def run(self):
while True:
customer=Customer()
self.mutex.acquire()
if self.queue.full():
print "Queue is full : Cant Enter Critical Section"
elif not self.queue.full():
# NOTE 2: other threads can enter after releasing the lock
print self.mutex.release()
self.mutex.acquire()
#Critical Section
self.queue.put(customer)
print "Customer %d Enters the Queue with %d service " %(
customer.id,customer.serviceTime
)
# Note 1 alternative - release mutex (cancel 'if' branching effect)
self.mutex.release()
I actually fail to understand it's logic. You release the lock allowing threads to check the queue while others thread push to the queue, but you're aassuming the queue isn't thread-safe.
If you are using the queue's thread-safety, than why use mutex to begin with?
Edit: The main problem is, as specified, you're acquiring the mutex twice with the producer. You can only acquire the mutex once (at-least if it's a threading.Lock
object). Try this code in your interperter:
>>> import threading
>>> lock = threading.Lock()
>>> lock.acquire()
True
>>> lock.acquire()
And see what happens.
Either way, figure out the logic for your critical section. The fixed code (NOTE 1) should prevent the blocking you're experiencing due to not releasing the mutex on the first if branch.
Good luck.