Кроме всего прочего, в примере 10.19 вместо модуля _thread используется модуль threading. Это означает, что в отличие от предыдущей версии, программа не завершится, пока выполняются какие-либо потоки- производители, если только они не были запущены как потоки-демоны, установкой их флагов daemon в значение True. Напомню, что при использовании модуля threading программы завершаются, только когда остаются одни потоки-демоны, — потоки-производители наследуют значение False в атрибуте daemon от потока, создавшего их, что препятствует завершению программы, пока они продолжают выполняться.
Однако в данном примере дочерние потоки выполнения завершаются слишком быстро, чтобы можно было заметить задержку при завершении программы. Измените в сценарии вызов функции time.sleep, чтобы он выполнял задержку на 2 секунды, имитируя долгоживущий рабочий поток, и попробуйте запустить пример. Попытка закрыть окно после щелчка левой кнопкой мыши сотрет окно, но сама программа продолжит выполняться еще в течение примерно 10 секунд (это можно наблюдать, например, в виде паузы в окне консоли). Если сделать то же самое в предыдущей версии, использующей модуль _thread, или в этой версии установить флаги daemon потоков в значение True, программа будет завершаться немедленно.
При решении практических задач может потребоваться взвесить различные политики управления завершением в контексте действующих потоков и программировать их соответствующим образом; при необходимости отложить завершение программы можно использовать потоки, запущенные со значением False в атрибуте daemon, или блокировки. Напротив, использование потоков threading может препятствовать желательному завершению программы, если забыть установить флаг daemon в значение True. Дополнительно о завершении программ и о потоках- демонах (и о других пугающих темах!) рассказывается в главе 5.
Использованная литература:
Марк Лутц — Программирование на Python, 4-е издание, I том, 2011