私は、マルチスレッドのPythonプログラムの下で、Python 3.4.3インタプリタを使って実行しようとしました。 私は、dish_queue内のすべてのアイテムが取得されて処理された後(つまり、これはtask_done関数の目的です)、dish_queueはプログラムをそれ以上ブロックしないので、プログラムは正常に終了できます。マルチスレッドのPythonプログラムは決して終了しません
Drying desert <Thread(Thread-2, started 140245865154304)>
の行が印刷された後の結果は、dish_queue.join()
行がコメントされているかどうかに関係なく、プログラムは終了しません。 メインスレッドはステートメントwasher(dishes,dish_queue)
に固執しているようですか?なぜ誰かが私に説明することができますか?
$ cat threading_dish.py
import threading,queue
import time
def washer(dishes,dishqueue):
for dish in dishes:
time.sleep(5)
print("washing",dish,threading.current_thread())
time.sleep(5)
dishqueue.put(dish)
def dryer(dishqueue):
while True:
dish=dishqueue.get()
print("Drying",dish,threading.current_thread())
#time.sleep(10)
dishqueue.task_done()
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()
$ python3 threading_dish.py
washing salad <_MainThread(MainThread, started 140245895784256)>
Drying salad <Thread(Thread-1, started 140245873547008)>
washing bread <_MainThread(MainThread, started 140245895784256)>
Drying bread <Thread(Thread-2, started 140245865154304)>
washing entree <_MainThread(MainThread, started 140245895784256)>
Drying entree <Thread(Thread-1, started 140245873547008)>
washing desert <_MainThread(MainThread, started 140245895784256)>
Drying desert <Thread(Thread-2, started 140245865154304)>
これに対して、私がプログラムの複数処理の対応部分を実行すると、プログラムは最後の印刷後に正常に終了することができます。 マルチスレッドとマルチプロセッシングの違いは、結果が逆になっていることですか?
$ cat multiprocessing_dishes.py
import multiprocessing as mp
import time
def washer(dishes,output):
for dish in dishes:
print('washing', dish, 'dish',mp.current_process())
output.put(dish)
def dryer(input):
while True:
dish=input.get()
print('Drying',dish,'dish',mp.current_process())
time.sleep(5)
input.task_done()
dishqueue=mp.JoinableQueue()
dryerproc=mp.Process(target=dryer,args=(dishqueue,))
dryerproc.daemon=True
dryerproc.start()
dishes=['xxx','asa','aass']
washer(dishes,dishqueue)
dishqueue.join()
$ python3 multiprocessing_dishes.py
washing xxx dish <_MainProcess(MainProcess, started)>
washing asa dish <_MainProcess(MainProcess, started)>
washing aass dish <_MainProcess(MainProcess, started)>
Drying xxx dish <Process(Process-1, started daemon)>
Drying asa dish <Process(Process-1, started daemon)>
Drying aass dish <Process(Process-1, started daemon)>
$
プログラムのマルチプロセッシングの対応部分を追加しましたが、JoinableQueue.get()はブロックしませんでした。なぜそのような違いがありますか? – Zii
2番目の例では、ドライヤースレッドはデーモンスレッドです。デーモンスレッドは、終了を妨げないスレッドです。つまり、アプリケーションの実行可能スレッドおよびブロックされたスレッドがすべてデーモンスレッドである場合、アプリケーションは終了します。ドライバースレッド**はQueue.get()でブロックしますが、プロセスが終了するのを防ぐだけでなく、メインスレッドが実行を終了するとプロセスが終了します。メインスレッド(または別の非デーモンスレッド)にもっと多くの作業があった場合、デーモンスレッドはブロックされたままなので、これは一般的には悪い解決策であると私は言います。 –