Я изучал потоки Python и наткнулся join()
.
Автор сказал, что если поток находится в режиме демона, то мне нужно использовать его, join()
чтобы поток мог завершить себя до завершения основного потока.
но я также видел его использование, t.join()
хотя t
не былоdaemon
пример кода это
import threading
import time
import logging
logging.basicConfig(level=logging.DEBUG,
format='(%(threadName)-10s) %(message)s',
)
def daemon():
logging.debug('Starting')
time.sleep(2)
logging.debug('Exiting')
d = threading.Thread(name='daemon', target=daemon)
d.setDaemon(True)
def non_daemon():
logging.debug('Starting')
logging.debug('Exiting')
t = threading.Thread(name='non-daemon', target=non_daemon)
d.start()
t.start()
d.join()
t.join()
я не знаю, что использовать, так t.join()
как это не демон, и я не вижу изменений, даже если я удалю его
python
multithreading
python-multithreading
user192362127
источник
источник
Ответы:
Несколько неуклюжий ascii-art для демонстрации механизма:
join()
предположительно вызывается основным потоком. Он также может быть вызван другим потоком, но излишне усложнит диаграмму.join
-calling должен быть помещен в дорожку основного потока, но чтобы выразить отношение потока и сделать его как можно более простым, я решил вместо этого поместить его в дочерний поток.Поэтому причина, по которой вы не видите никаких изменений, заключается в том, что ваш основной поток ничего не делает после вашего
join
. Вы могли бы сказать, чтоjoin
это (только) имеет отношение к потоку выполнения основного потока.Например, если вы хотите одновременно загрузить несколько страниц, чтобы объединить их в одну большую страницу, вы можете начать одновременную загрузку с использованием потоков, но нужно дождаться окончания последней страницы / потока, прежде чем приступить к сборке одной страницы. из многих. Вот когда вы используете
join()
.источник
demon_thread.join(0.0)
,join()
по умолчанию блокирующего без учета daemonized атрибута. Но присоединение к демонизированному потоку, скорее всего, может привести к неприятностям! Сейчас я собираюсь удалитьjoin()
вызов из моей маленькой диаграммы для потока демонов ...daemon=True
, не нужноjoin()
ли нам, если нам нужноjoin()
в конце кода?main thread
завершится, завершится ли программа, не давchild-thread(long)
завершить самому запуску (т.child-thread(long)
Е. Не завершится полностью)?Прямо из документов
Это означает, что основная нить, которая порождает
t
иd
ожидаетt
завершения, пока не закончится.В зависимости от логики, которую использует ваша программа, вы можете дождаться завершения потока, прежде чем ваш основной поток продолжится.
Также из документов:
Простой пример, скажем, у нас есть это:
Который заканчивается:
Это выведет:
Здесь главный поток явно ожидает завершения
t
потока, пока он не вызоветprint
второй раз.В качестве альтернативы, если бы у нас было это:
Мы получим этот вывод:
Здесь мы делаем свою работу в главном потоке, а затем ждем окончания
t
потока. В этом случае мы могли бы даже удалить явное соединение,t.join()
и программа будет неявно ждатьt
завершения.источник
t.join()
. добавив сон спать или что-то еще. на данный момент я могу видеть любой изменения в программе, даже если я использую это или нет. но для damemon я могу видеть его выход, если я использую,d.join()
который я не вижу, когда я не использую d.join ()Спасибо за эту ветку - она мне тоже очень помогла.
Я кое-что узнал о .join () сегодня.
Эти потоки работают параллельно:
и они запускаются последовательно (не то, что я хотел):
В частности я пытался привести в порядок и привести в порядок
Это работает! Но это работает последовательно. Я могу поместить self.start () в __ init __, но не в self.join (). Это должно быть сделано после каждый поток был запущен.
join () - это то, что заставляет основной поток ждать завершения вашего потока. В противном случае ваш поток запускается сам по себе.
Таким образом, один из способов представить join () как «удержание» в основном потоке - это своего рода удаление потоков из вашего потока и последовательное выполнение в основном потоке, прежде чем основной поток сможет продолжить. Это гарантирует, что ваш поток завершен, прежде чем основной поток продвигается вперед. Обратите внимание, что это означает, что все в порядке, если ваш поток уже завершен до того, как вы вызовете join () - основной поток просто освобождается сразу после вызова join ().
На самом деле, мне только что пришло в голову, что основной поток ожидает d.join (), пока поток d не завершит свою работу, прежде чем перейдет к t.join ().
На самом деле, чтобы быть очень ясным, рассмотрим этот код:
Он производит этот вывод (обратите внимание, как операторы печати встраиваются друг в друга.)
T1.join () поддерживает основной поток. Все три потока завершаются до того, как завершается t1.join (), и основной поток продолжает выполнение print, затем t2.join (), затем print, затем t3.join (), затем print.
Исправления приветствуются. Я также новичок в потоках.
(Примечание: в случае, если вам интересно, я пишу код для DrinkBot, и мне нужны потоки, чтобы запускать насосы ингредиентов одновременно, а не последовательно - меньше времени для ожидания каждого напитка.)
источник
Метод join ()
Источник: http://docs.python.org/2/library/threading.html
источник
t.join()
и программа все еще ждет его до завершения. я не вижу здесь никакогоt.join()
Простое понимание,
with join - интерпретатор будет ждать, пока ваш процесс не будет завершен или завершен
без соединения - интерпретатор не будет ждать завершения процесса ,
источник
При создании
join(t)
функции как для потока, не являющегося демоном, так и для потока демона, основной поток (или основной процесс) должен подождатьt
несколько секунд, а затем продолжить работу над своим собственным процессом. В течениеt
секунд ожидания оба дочерних потока должны делать то, что они могут, например, распечатывать текст. Черезt
несколько секунд, если поток, не являющийся демоном, все еще не завершил свою работу, и он все еще может завершить его после того, как основной процесс завершит свою работу, но для потока демона он просто пропустил свое окно возможностей. Тем не менее, он в конечном итоге умрет после выхода из программы Python. Пожалуйста, поправьте меня, если что-то не так.источник
В python 3.x join () используется для объединения потока с основным потоком, т.е. когда join () используется для определенного потока, основной поток прекращает выполнение до тех пор, пока не завершится выполнение присоединенного потока.
источник
Этот пример демонстрирует
.join()
действие:Вне:
источник
Есть несколько причин для основного потока (или любого другого потока) присоединиться к другим потокам
Поток мог создать или удерживать (блокировать) некоторые ресурсы. Поток, выполняющий соединение, может очистить ресурсы от своего имени.
join () - это естественный блокирующий вызов для потока, вызывающего соединение, для продолжения после завершения вызываемого потока.
Если программа python не присоединяется к другим потокам, интерпретатор python по-прежнему присоединяется к потокам, не являющимся демонами, от своего имени.
источник
"Какая польза от использования join ()?" ты говоришь. Действительно, это тот же ответ, что и «зачем использовать закрытие файлов, так как python и ОС закроют мой файл для меня, когда выйдет моя программа?».
Это просто вопрос хорошего программирования. Вы должны присоединиться () к вашим потокам в той точке кода, которую поток не должен больше должен работать, либо потому, что вы должны убедиться, что поток не работает, чтобы мешать вашему собственному коду, либо что вы хотите правильно вести себя в большая система.
Вы можете сказать: «Я не хочу, чтобы мой код задерживал предоставление ответа» только из-за дополнительного времени, которое может потребоваться join (). Это может быть совершенно справедливо в некоторых сценариях, но теперь вы должны принять во внимание, что ваш код "оставляет желать лучшего для python и операционной системы для очистки". Если вы делаете это по причинам производительности, я настоятельно рекомендую вам задокументировать это поведение. Это особенно верно, если вы создаете библиотеку / пакет, который, как ожидается, будут использовать другие.
Там нет причин , чтобы не присоединиться (), кроме соображений производительности, и я бы сказал , что ваш код не должен выполнять эту скважину.
источник
join()
.