在Python中使用条件对象的生产者-消费者实现中有什么错误吗?

在Python中使用条件对象的生产者-消费者实现中有什么错误吗?,python,multithreading,Python,Multithreading,有人能告诉我下面用python实现生产者-消费者问题的代码有什么错误吗。我正在使用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 l

有人能告诉我下面用python实现生产者-消费者问题的代码有什么错误吗。我正在使用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()
程序输出:

Produced  0
Produced  1
Produced  2
Produced  3
Queue is full and size =  4
然后它卡住了。终止程序时,我得到:

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
回溯(最近一次呼叫最后一次):
文件“path/t.py”,第47行,在
pThread=Thread(target=p.run(),args=())
文件“path/t.py”,第22行,运行中
等一下
文件“/usr/lib/python3.4/threading.py”,第289行,正在等待
服务员
键盘中断
生产者似乎并不“不适合”消费者。有人能告诉我为什么吗


非常感谢

锁定和解锁都可以,但您可能希望将“run”指定为目标,而不是“run()

:-)

说明:让我们简化一下

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())
您可以在堆栈跟踪中看到,它从未超出第47行,这是

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

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

看起来您从未从生产者代码中释放锁。(这是我使用C条件变量的经验,因此在Python中可能有所不同);成功生产后,锁将在“带cvP”的出口处释放,即在cvC.notify()之后释放。这是我的理解。我也是Python新手。我上多线程操作系统课程已经有一段时间了,但是while检查不应该改为if语句吗?我认为没有理由使用“while(len(q)==0)”而不是“if(len(q)==0)”,因为您已经在while循环中等待了。当它被通知/唤醒时,条件应该已经满足。@user3085290要与多个生产者和消费者保持稳定。@郭华柳在
cvP.notify()
消费完
Consumer()!去掉括号后效果很好。你能解释一下为什么这个语法问题会导致运行问题吗?非常感谢你@国华流-如果有帮助,别忘了接受答案:-D
x = p.run()
pThread = Thread(x, args=())