Is there something wrong with my Python Producer-Consumer implementation using condition objects?

Can someone tell me what is wrong in my code below, which implements the consumer-producer problem in python. I am using Python 3.4

import threading from threading import Thread from collections import deque import time maxSize = 4 # maximum size of the queue q = deque([]) cur = 0 # current value to push into the queue lk = threading.Lock() cvP = threading.Condition(lk) # condition object for consumer cvC = threading.Condition(lk) # condition object for producer class Producer: def run(self): global maxSize, q, cur while True: with cvP: while len(q) >= maxSize: print( "Queue is full and size = ", len(q) ) cvC.notify() # notify the Consumer cvP.wait() # put Producer to wait q.append(cur) print("Produced ", cur) cur = cur + 1 cvC.notify() # notify the Consumer class Consumer: def run(self): global maxSize, q, cur while True: with cvC: while len(q) == 0: print( "Queue is empty and size = ", len(q) ) cvP.notify() # notify the Producer cvC.wait() # put Consumer to wait x = q.popleft() print("Consumed ", x) time.sleep(1) cvP.notify() # notify the Producer p = Producer() c = Consumer() pThread = Thread( target=p.run(), args=()) cThread = Thread( target=c.run(), args=()) pThread.start() cThread.start() pThread.join() cThread.join() 

Program Output:

 Produced 0 Produced 1 Produced 2 Produced 3 Queue is full and size = 4 

Then he got stuck. At the end of the program, I received:

 Traceback (most recent call last): File "path/t.py", line 47, in <module> pThread = Thread( target=p.run(), args=()) File "path/t.py", line 22, in run cvP.wait() File "/usr/lib/python3.4/threading.py", line 289, in wait waiter.acquire() KeyboardInterrupt 

The producer did not seem to be a "godless" consumer. Can someone tell me why?

Thank you very much in advance!

+6
source share
1 answer

Locking and unlocking is great, but you probably want to specify "run" as the target, not "run ()"

 pThread = Thread( target=p.run, args=()) cThread = Thread( target=c.run, args=()) 

:-)

Explanation: allows you to simplify

 def foo(): # .. # Foo will run on a new thread Thread(target=foo) # foo() is run before the thread is created, and its return # value is the target for the Thread call. Thread(target=foo()) 

In the stack trace, you can see that it never went beyond line 47, which

 pThread = Thread( target=p.run(), args=()) 

Same as

 x = p.run() pThread = Thread(x, args=()) 
+5
source

All Articles