Что вызывает вызов 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() 

Из моего понимания документации модуля в очереди, dish_queue.join () будет блокировать основной поток, пока количество незавершенных задач (здесь не испорченные тарелки) не вернется к 0. Но мне интересно, что случилось с 2 dry_thread.

Я обнаружил, что если я запускаю функцию dryer на пустой dish_queue в основной программе, программа застревает (BTW, это так называемый блок из dish_queue.get ()?). Поэтому, если dish_queue.join() разблокирует основной поток, сделайте 2 dry_thread также разблокированным и освободите память? Что означает блок в любом случае в очереди?

Короткий ответ на ваш главный вопрос – ничто.

Для более длительного ответа, вот два графика параллелизма, один без ожидания: введите описание изображения здесь

И один с: введите описание изображения здесь

Как вы можете видеть, в начале обе обе сушилки находятся в замке, который, как вы правильно поняли, является блоком get() . Теперь в первом случае основной поток заканчивается после завершения функции стиральной машины. При добавлении dish_queue.join() основной поток ожидает, что dish_queue завершит выполнение всех задач. Поэтому, когда вы говорите, что join() разблокирует основной поток, это означает, что он удаляет собственный блок. Как вы можете заметить, другие потоки полностью не затронуты им и остаются заблокированными.

Что касается блока, то когда поток или процесс ждут ввода извне потока или в этом случае ждут элемент в очереди. Если вы хотите остановить другие потоки, вам нужно либо добавить таймаут для get() (который будет генерировать исключение и убить поток), либо убить их после dish_queue.join() .