2016-08-02 1 views
4

私のコードは、dish_queue.join()未完了のタスクの数(ここでは未乾燥さディッシュ)まで、メインスレッドをブロックします0に戻しキューモジュールのドキュメント上の私の理解からメインスレッドのqueue.join()の呼び出しは、メイン以外のスレッドと何をしますか?

import time, queue, threading 

def washer(dishes, dish_queue): 
    for dish in dishes: 
     print ("Washing", dish) 
     time.sleep(1) 
     dish_queue.put(dish) 

def dryer(dish_queue): 
    while True: 
     dish = dish_queue.get() 
     print("Drying", dish) 
     time.sleep(2) 
     dish_queue.task_done() 
     print('dryer') 

dish_queue = queue.Queue() 
for n in range(2): 
    dryer_thread = threading.Thread(target=dryer, args=(dish_queue,)) 
    dryer_thread.start() 

dishes = ['salad', 'bread', 'entree', 'desert'] 
washer(dishes, dish_queue) 
dish_queue.join() 

、以下の通りです。しかし、私は2ドライヤー_スレッドに何が起こったのだろうか。

メインプログラムの空のdish_queueに関数dryerを実行すると、プログラムが停止しています(これは、いわゆるdish_queue.get()のブロックですか?)。したがって、dish_queue.join()がメインスレッドのブロックを解除した場合は、2 dryer_threadもブロックを解除してメモリを解放しますか? ブロックとは、とにかくキューdocの意味ですか?

答えて

1

あなたの主な質問に対する短い答えは何もありません。 enter image description here

そして1: enter image description here

あなたが見ることができるように、最初に両方の2つのドライヤースレッドがでている長い答えを

、ここでは2つの同時実行グラフ、待ち時間なしの1ですあなたが正しく理解しているように、ロックはget()のブロックです。さて、最初のケースでは、メインスレッドは、ウォッシャー機能の終了後に終了します。 dish_queue.join()を追加すると、メインスレッドはすべてのタスクを終了するためにdish_queueを待ちます。したがって、join()がメインスレッドのブロックを解除すると、それはそれ自身のブロックを削除することを意味します。ご覧のとおり、他のスレッドは完全に影響を受けず、ブロックされたままです。

ブロックとは、スレッドまたはプロセスがスレッドの外部からの入力を待機しているとき、またはこの場合はキュー内の要素を待機しているときです。他のスレッドを停止したい場合は、タイムアウトをget()に追加するか(例外をスローしてスレッドを強制終了する)、またはdish_queue.join()の後にそれらを強制終了する必要があります。

+0

タイムアウト値を設定する以外に、他のスレッドを終了するにはどうすればよいですか?他のスレッドをデーモンとして動作させるかどうかはわかりません。また、私のコードを変更せずにそれらをブロックし続けると、本当に私の記憶を消費しますか? – Nicholas

+0

ところで、どの並行処理モニタを使用していますか?それは上品です! – Nicholas

+0

一般に、ブロックを持つスレッドはスリープスレッドと同じです。それはメモリを解放しませんが、追加のリソースも消費しませんので、基本的にスレッドを将来必要とするかどうかによって異なります。注目すべきは、メインスレッドがアクティブである限り、スレッドはそこに存在するため、新しいスレッドをオープンして既存のキューに新しい要素を追加するべきではありません。 私はpyCharmを使用していますが、これはIDEの周りに最適です。 – Aruj

関連する問題