2017-09-19 12 views
0

これは私の現在のコードですが、主な問題はSemphoreを使用して2つのプロセスの出力を制御することですが、Semphoreがglobalyを変更しない、 Semporeを2に変更します。「消費者」はSemporeがゼロであると考えています。これは、それが永遠に待つ原因となります。セマフォの値がグローバルに変更されない理由

from multiprocessing import Process, Semaphore, Queue 
import time 
from random import random 

buffer = Queue(10) 
empty = Semaphore(2) 
full = Semaphore(0) 

class Consumer(Process): 

    def run(self): 
     global buffer, empty, full 
     while True: 
      time.sleep(4) 
      print(full) 
      full.acquire() 
      buffer.get() 
      print('Consumer get') 
      time.sleep(1) 
      empty.release() 


class Producer(Process): 

    def run(self): 
     global buffer, empty, full 
     while True: 
      empty.acquire() 
      print ('Producer put ') 
      time.sleep(1) 
      full.release() 
      buffer.put(1) 
      print(full) 


if __name__ == '__main__': 
    p = Producer() 
    c = Consumer() 
    p.daemon = c.daemon = True 
    p.start() 
    c.start() 
    p.join() 
    c.join() 
    print ('Ended!') 

、出力は私が「消費者」のプロセスが変更を検出させるために何をすべきかを知りません

Producer put 
<Semaphore(value=1)> 
Producer put 
<Semaphore(value=2)> 
<Semaphore(value=0)> 

です。

+0

これをProcessesに渡します: 'Process(args =(empty、)) '。ワーカー関数を使用しないので、 'self._args'を使ってargsにアクセスする必要があります。 – stovfl

答えて

0

2つのプロセスは、それぞれのプロセスがインスタンス化されるときにスクリプト内のコード全体を実行するため、2つのセマフォの両方のコピーを持っています。

あなたはif __name__ == '__main__':内セマフォやキューの定義を移動し、彼らは両方は、3つのオブジェクトの同じインスタンスを使用するようにProducerConsumerコンストラクタにセマフォのインスタンスを渡す必要があります。

from multiprocessing import Process, Semaphore, Lock, Queue 
import time 
from random import random 

class Consumer(Process): 
    def __init__(self, empty, full, buffer): 
     super(Consumer, self).__init__() 
     self.empty = empty 
     self.full = full 
     self.buffer = buffer 

    def run(self): 
     while True: 
      time.sleep(4) 
      print("Consumer: {}".format(self.full), flush=True) 
      print("Consumer: buf {}".format(self.buffer.qsize()), flush=True) 
      self.full.acquire() 
      self.buffer.get() 
      print('Consumer get', flush=True) 
      time.sleep(1) 
      self.empty.release() 


class Producer(Process): 
    def __init__(self, empty, full, buffer): 
     super(Process, self).__init__() 
     self.empty = empty 
     self.full = full 
     self.buffer = buffer 

    def run(self): 
     while True: 
      self.empty.acquire() 
      print ('Producer put ', flush=True) 
      self.buffer.put('a') #<<<<<<<<<<< you forgot this in your code. If the queue is empty, get() will block on the consumer 
      time.sleep(1) 
      self.full.release() 
      print(self.full, flush=True) 


if __name__ == '__main__': 
    buffer = Queue(10) 
    empty = Semaphore(2) 
    full = Semaphore(0) 

    p = Producer(empty, full, buffer) 
    c = Consumer(empty, full, buffer) 
    p.daemon = c.daemon = True 
    p.start() 
    c.start() 
    p.join() 
    c.join() 
    print ('Ended!') 
+1

GPhilo素早い対応をいただきありがとうございます。私はあなたの指示に先立ち、自分自身でコードを公開しました。あなたのコードには間違いが1つあります。プロデューサプロセスの終わりに 'print(self.full、flush = True)'でなければなりません。とにかく助けてくれてありがとう! –

+0

タイプミスをキャッチしてくれてありがとう!私は答えを更新:) – GPhilo

関連する問題