J'étudiais le filetage python et suis tombé sur join()
.
L'auteur a dit que si le thread est en mode démon, je dois l'utiliser join()
pour que le thread puisse se terminer avant la fin du thread principal.
mais je l'ai également vu utiliser t.join()
même si ce t
n'était pasdaemon
exemple de code est-ce
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()
Je ne sais pas à quoi t.join()
ça sert car ce n'est pas un démon et je ne vois aucun changement même si je le supprime
python
multithreading
python-multithreading
user192362127
la source
la source
Réponses:
Un ascii-art quelque peu maladroit pour démontrer le mécanisme: le
join()
est vraisemblablement appelé par le fil principal. Il pourrait également être appelé par un autre thread, mais compliquerait inutilement le diagramme.join
-l'appel devrait être placé dans la piste du thread principal, mais pour exprimer la relation de thread et la garder aussi simple que possible, je choisis de le placer dans le thread enfant à la place.Donc, la raison pour laquelle vous ne voyez aucun changement est que votre thread principal ne fait rien après votre
join
. On pourrait dire quejoin
c'est (seulement) pertinent pour le flux d'exécution du thread principal.Si, par exemple, vous souhaitez télécharger simultanément un tas de pages pour les concaténer en une seule grande page, vous pouvez démarrer des téléchargements simultanés à l'aide de threads, mais vous devez attendre la fin de la dernière page / thread avant de commencer à assembler une seule page. sur beaucoup. C'est alors que vous utilisez
join()
.la source
demon_thread.join(0.0)
,join()
est par défaut de blocage sans tenir compte de l'attribut daemon. Mais rejoindre un fil diabolisé ouvre très probablement un ensemble de problèmes! J'envisage maintenant de supprimer l'join()
appel dans mon petit diagramme pour le thread démon ...daemon=True
-nous pas besoin dejoin()
si nous avons besoin de lajoin()
fin du code?main thread
fin, le programme se terminera-t-il sans laisser lachild-thread(long)
finition s'exécuter lui-même (c'estchild-thread(long)
-à- dire qu'il n'est pas complètement terminé)?Directement des documents
Cela signifie que le thread principal qui apparaît
t
etd
attendt
jusqu'à ce qu'il se termine.Selon la logique utilisée par votre programme, vous souhaiterez peut-être attendre la fin d'un thread avant de poursuivre votre thread principal.
Également à partir des documents:
Un exemple simple, disons que nous avons ceci:
Qui se termine par:
Cela produira:
Ici, le thread principal attend explicitement la
t
fin du thread jusqu'à ce qu'il appelleprint
la deuxième fois.Alternativement, si nous avions ceci:
Nous obtiendrons cette sortie:
Ici, nous faisons notre travail dans le thread principal, puis nous attendons que le
t
thread se termine. Dans ce cas, nous pourrions même supprimer la jointure explicitet.join()
et le programme attendra implicitement lat
fin.la source
t.join()
. en ajoutant du sommeil ou quelque chose d'autre. au moment où je peux voir n'importe quel chnage dans le programme même si je l'utilise ou non. mais pour damemon je peux voir sa sortie si j'utilised.join()
ce que je ne vois pas quand je n'utilise pas d.join ()Merci pour ce fil - cela m'a beaucoup aidé aussi.
J'ai appris quelque chose sur .join () aujourd'hui.
Ces threads s'exécutent en parallèle:
et ceux-ci fonctionnent séquentiellement (pas ce que je voulais):
En particulier, j'essayais d'intelligent et de bien rangé:
Cela marche! Mais cela fonctionne séquentiellement. Je peux mettre self.start () dans __ init __, mais pas self.join (). Cela doit être fait après le démarrage de chaque thread.
join () est ce qui fait que le thread principal attend la fin de votre thread. Sinon, votre thread s'exécute tout seul.
Donc, une façon de penser à join () comme un "hold" sur le thread principal - il sorte de dé-thread votre thread et s'exécute séquentiellement dans le thread principal, avant que le thread principal puisse continuer. Il garantit que votre thread est terminé avant que le thread principal n'avance. Notez que cela signifie que tout va bien si votre thread est déjà terminé avant d'appeler join () - le thread principal est simplement libéré immédiatement lorsque join () est appelé.
En fait, il me vient juste à l'esprit que le thread principal attend à d.join () jusqu'à ce que le thread d se termine avant de passer à t.join ().
En fait, pour être très clair, considérez ce code:
Il produit cette sortie (notez comment les instructions d'impression sont enfilées les unes dans les autres.)
Le t1.join () maintient le thread principal. Les trois threads se terminent avant la fin de t1.join () et le thread principal passe à l'exécution de l'impression, puis de t2.join () puis de l'impression, puis de t3.join (), puis de l'impression.
Les corrections sont les bienvenues. Je suis également nouveau dans le filetage.
(Remarque: au cas où vous seriez intéressé, j'écris du code pour un DrinkBot, et j'ai besoin d'un filetage pour exécuter les pompes à ingrédients simultanément plutôt que séquentiellement - moins de temps à attendre pour chaque boisson.)
la source
La méthode join ()
Source: http://docs.python.org/2/library/threading.html
la source
t.join()
et le programme l'attend toujours avant la fin. je ne vois aucune utilisation d't.join()
ici dans mon codeSimple comprendre,
avec join - l'interprète attendra que votre processus soit terminé ou terminé
sans se joindre - interprète attendre jusqu'à ce que l' habitude de se processus terminé ,
la source
Lors de la création d'une
join(t)
fonction pour un thread non démon et un thread démon, le thread principal (ou processus principal) doit attendret
quelques secondes, puis peut aller plus loin pour travailler sur son propre processus. Pendant let
temps d'attente des secondes, les deux fils enfants doivent faire ce qu'ils peuvent faire, comme imprimer du texte. Après lest
secondes, si le thread non démon n'a toujours pas terminé son travail, et il peut toujours le terminer après que le processus principal a terminé son travail, mais pour le thread démon, il a juste raté sa fenêtre d'opportunité. Cependant, il finira par mourir après la fin du programme python. Veuillez me corriger s'il y a quelque chose qui ne va pas.la source
En python 3.x, join () est utilisé pour joindre un thread avec le thread principal, c'est-à-dire que lorsque join () est utilisé pour un thread particulier, le thread principal arrêtera de s'exécuter jusqu'à ce que l'exécution du thread joint soit terminée.
la source
Cet exemple illustre l'
.join()
action:En dehors:
la source
Il y a quelques raisons pour que le thread principal (ou tout autre thread) rejoigne d'autres threads
Un thread peut avoir créé ou contenir (verrouiller) certaines ressources. Le thread appelant à joindre peut être en mesure d'effacer les ressources en son nom
join () est un appel de blocage naturel pour que le thread appelant la jointure continue après la fin du thread appelé.
Si un programme python ne joint pas d'autres threads, l'interpréteur python joindra toujours les threads non démons en son nom.
la source
"Quelle est l'utilité d'utiliser join ()?" vous dites. Vraiment, c'est la même réponse que "quelle est l'utilité de fermer des fichiers, car python et le système d'exploitation fermeront mon fichier pour moi lorsque mon programme se fermera?".
C'est simplement une question de bonne programmation. Vous devez joindre () vos threads au point dans le code que le thread ne doit pas être exécuté, soit parce que vous devez vous assurer que le thread ne s'exécute pas pour interférer avec votre propre code, soit que vous souhaitez vous comporter correctement dans un système plus grand.
Vous pourriez dire «Je ne veux pas que mon code retarde la réponse» simplement à cause du temps supplémentaire que la jointure () pourrait nécessiter. Cela peut être parfaitement valable dans certains scénarios, mais vous devez maintenant tenir compte du fait que votre code "laisse la saloperie pour python et le système d'exploitation à nettoyer". Si vous le faites pour des raisons de performances, je vous encourage fortement à documenter ce comportement. Cela est particulièrement vrai si vous créez une bibliothèque / un package que d'autres sont censés utiliser.
Il n'y a aucune raison de ne pas se joindre à (), autres que des raisons de performance, et je dirais que votre code n'a pas besoin d'effectuer que bien.
la source
join()
.