1

对于生产者-消费者问题,我提出了这个解决方案:

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)循环并让每个线程只在循环中运行块时,它就会达到死锁,我不明白为什么。

4

2 回答 2

3

生产者-消费者模式可以很容易地使用 Python 的内置队列支持来实现:

这可以简化您的代码。调度程序也非常有用:

由于您的问题是用 Python-3.x 标记的,因此您绝对应该看看 concurrent.futures 模块:

您的工人可以是任务,而桶可以成为队列。

于 2013-03-05T01:28:21.693 回答
0

显然问题是,从等待中醒来后,您重新获取锁,因此现在注释掉的获取将阻塞。

于 2013-03-04T23:22:03.967 回答