Czy ktoś może mi powiedzieć, co jest nie tak w moim poniższym kodzie, który implementuje problem producent-konsument w python. Używam Python 3.4Coś nie tak w mojej implementacji Producent-Konsument w Pythonie przy użyciu obiektów warunkowych?
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()
Wyjście Program:
Produced 0
Produced 1
Produced 2
Produced 3
Queue is full and size = 4
Potem utknąłem. Po zakończeniu programu otrzymałem:
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
Producent nie wydawał się "nofity" konsumentem. Czy ktoś może mi powiedzieć, dlaczego?
Wielkie dzięki z góry!
Wygląda jak nigdy zwolnić blokadę od kod producenta. (To jest z mojego doświadczenia ze zmiennymi warunkowymi C, więc może być inaczej w Pythonie). – Xaqq
Dla producenta: w momencie oczekiwania blokada zostanie zwolniona przez cvP.wait(); po pomyślnym wytworzeniu blokada zostanie zwolniona przy wyjściu "z cvP", tj. po cvC.notify(). To jest moje zrozumienie. Jestem również nowy w Pythonie. –
Minęło trochę czasu, odkąd wziąłem udział w kursie wielowątkowego systemu operacyjnego, ale czy nie powinno się sprawdzać, czy zamiast tego są instrukcje? Nie widzę powodu, aby używać "while (len (q) == 0)" powyżej "if (len (q) == 0)", ponieważ już czekałeś wewnątrz pętli while. Kiedy zostanie powiadomiony/obudzony, warunek powinien już być spełniony. – user3085290