我尝试使用python 3.4.3解释器在多线程python程序下运行。 我的期望是,在获取并处理了dish_queue中的所有项目之后(这是函数task_done的目的,对吗?),dish_queue将不再阻止程序,因此程序可以正常退出。
结果是在打印出行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)>
$
答案 0 :(得分:0)
https://docs.python.org/3.4/library/queue.html
Queue.get()阻塞,因此在不再生成队列之后,干燥器线程将无限期地阻塞。 您需要以某种方式向干燥器螺纹发出洗涤过程已完成的信号。
您可以通过在while循环条件中查询共享变量来实现此目的,或者通过为每个线程排列毒丸来实现此目的。毒丸是预先确定的值,它允许消费线程知道它需要终止。