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

Producer-Consumer パターンは、Python の組み込み Queue サポートを使用して簡単に実装できます。

これにより、コードを簡素化できます。スケジューラも非常に便利です。

そして、あなたの質問は Python-3.x でタグ付けされているので、concurrent.futures モジュールを確認する必要があります。

ワーカーがタスクになり、バケットがキューになる可能性があります。

于 2013-03-05T01:28:21.693 に答える
0

どうやら問題は、待機から復帰した後、ロックを再取得すると、コメントアウトされた取得がブロックされることです。

于 2013-03-04T23:22:03.967 に答える