对于生产者 - 消费者问题,我提出了这个解决方案:
import threading
import random
import time
class Bucket:
def __init__(self, size):
self.size = size
self.current_size = 0
self.cond_var = threading.Condition()
def available_for_put(self):
return self.current_size < self.size
def available_for_get(self):
return self.current_size > 0
def put(self):
self.current_size = self.current_size + 1
print(self)
self.cond_var.notify_all()
def get(self):
self.current_size = self.current_size - 1
print(self)
self.cond_var.notify_all()
def acquire(self):
self.cond_var.acquire()
def release(self):
self.cond_var.release()
def wait(self):
self.cond_var.wait()
def __str__(self):
return "Size is {0}".format(self.current_size)
class Worker(threading.Thread):
PRODUCER = 1
CONSUMER = 0
def __init__(self, bucket, kind):
threading.Thread.__init__(self)
self.kind = kind
self.bucket = bucket
def run(self):
while(1):
self.bucket.acquire()
while(((self.kind == Worker.PRODUCER) and (not self.bucket.available_for_put())) or \
((self.kind == Worker.CONSUMER) and (not self.bucket.available_for_get()))):
self.bucket.wait()
### self.bucket.acquire()
if self.kind == Worker.PRODUCER:
self.bucket.put()
else:
self.bucket.get()
time.sleep(0.1)
self.bucket.release()
bucket = Bucket(10)
workers = []
for i in range(10):
workers.append(Worker(bucket, i % 2))
for w in workers:
w.start()
print("Thread started")
for w in workers:
w.join()
显然,如果我删除了while(1)
循环并让每个线程在循环内运行块只有一旦它到达死锁并且我无法理解为什么。
答案 0 :(得分:3)
可以使用Python的内置队列支持轻松实现Producer-Consumer模式:
这可以简化您的代码。调度程序也很有用:
既然你的问题是用Python-3.x标记的,那么你一定要看看concurrent.futures模块:
你的工作人员可能是任务,而存储桶可能会成为一个队列。
答案 1 :(得分:0)
显然问题是,从等待中醒来后你重新获得锁定,因此现在注释掉的获取将会阻止。