Ich habe das Python-Threading studiert und bin darauf gestoßen join()
.
Der Autor sagte, wenn sich der Thread im Daemon-Modus befindet, muss ich ihn verwenden, join()
damit der Thread sich selbst beenden kann, bevor der Haupt-Thread beendet wird.
aber ich habe ihn auch benutzen sehen t.join()
, obwohl t
es nicht wardaemon
Beispielcode ist dies
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()
Ich weiß nicht, was verwendet wird, t.join()
da es kein Daemon ist und ich keine Änderung sehen kann, selbst wenn ich es entferne
python
multithreading
python-multithreading
user192362127
quelle
quelle
Antworten:
Eine etwas ungeschickte ASCII-Kunst, um den Mechanismus zu demonstrieren: Die
join()
wird vermutlich vom Hauptfaden genannt. Es könnte auch von einem anderen Thread aufgerufen werden, würde das Diagramm jedoch unnötig komplizieren.join
-calling sollte in der Spur des Haupt-Threads platziert werden, aber um die Thread-Beziehung auszudrücken und sie so einfach wie möglich zu halten, habe ich mich dafür entschieden, sie stattdessen im untergeordneten Thread zu platzieren.Der Grund, warum Sie keine Änderungen sehen, ist, dass Ihr Haupt-Thread nichts nach Ihrem tut
join
. Man könnte sagen, esjoin
ist (nur) relevant für den Ausführungsfluss des Hauptthreads.Wenn Sie beispielsweise mehrere Seiten gleichzeitig herunterladen möchten, um sie zu einer einzigen großen Seite zu verketten, können Sie gleichzeitige Downloads mithilfe von Threads starten, müssen jedoch warten, bis die letzte Seite / der letzte Thread fertig ist, bevor Sie mit dem Zusammenstellen einer einzelnen Seite beginnen von vielen. Das ist, wenn Sie verwenden
join()
.quelle
demon_thread.join(0.0)
,join()
ist standardmäßig ohne Rücksicht auf das daemonisierte Attribut blockiert. Aber das Beitreten zu einem dämonisierten Thread eröffnet höchstwahrscheinlich eine ganze Dose Ärger! Ich denke jetzt darüber nach, denjoin()
Aufruf in meinem kleinen Diagramm für den Daemon-Thread zu entfernen ...daemon=True
setzen, brauchen wir nicht das,join()
wenn wir dasjoin()
am Ende des Codes brauchen ?main thread
Wird das Programm im ersten Fall nach Beendigung beendet, ohne dass daschild-thread(long)
Ende selbst ausgeführt wird (dhchild-thread(long)
nicht vollständig abgeschlossen ist)?Direkt aus den Dokumenten
Dies bedeutet, dass der Haupt-Thread, der erscheint
t
undd
wartet,t
bis er fertig ist, beendet wird.Abhängig von der Logik, die Ihr Programm verwendet, möchten Sie möglicherweise warten, bis ein Thread beendet ist, bevor Ihr Hauptthread fortgesetzt wird.
Auch aus den Dokumenten:
Ein einfaches Beispiel, sagen wir, wir haben folgendes:
Was endet mit:
Dies wird Folgendes ausgeben:
Hier wartet der Master-Thread explizit auf das
t
Ende des Threads, bis erprint
das zweite Mal aufgerufen wird.Alternativ, wenn wir dies hatten:
Wir werden diese Ausgabe erhalten:
Hier machen wir unsere Arbeit im Haupt-Thread und warten dann, bis der
t
Thread fertig ist. In diesem Fall entfernen wir möglicherweise sogar die explizite Verknüpfung,t.join()
und das Programm wartet implizit auft
den Abschluss.quelle
t.join()
. durch Hinzufügen von Schlaf oder etwas anderem. Im Moment kann ich jede Änderung im Programm sehen, selbst wenn ich es benutze oder nicht. aber für damemon kann ich seinen Ausgang sehen, wenn ich benutze,d.join()
was ich nicht sehe, wenn ich d.join () nicht benutzeDanke für diesen Thread - er hat mir auch sehr geholfen.
Ich habe heute etwas über .join () gelernt.
Diese Threads laufen parallel:
und diese laufen nacheinander (nicht das, was ich wollte):
Insbesondere habe ich versucht, klug und ordentlich zu sein:
Das funktioniert! Aber es läuft nacheinander. Ich kann self.start () in __ init __ einfügen, aber nicht self.join (). Dies muss erfolgen, nachdem jeder Thread gestartet wurde.
join () bewirkt, dass der Hauptthread auf das Ende Ihres Threads wartet. Andernfalls wird Ihr Thread von selbst ausgeführt.
Eine Möglichkeit, sich join () als "Halten" des Hauptthreads vorzustellen, besteht darin, den Thread zu entfädeln und nacheinander im Hauptthread auszuführen, bevor der Hauptthread fortgesetzt werden kann. Es stellt sicher, dass Ihr Thread vollständig ist, bevor sich der Haupt-Thread vorwärts bewegt. Beachten Sie, dass dies in Ordnung ist, wenn Ihr Thread bereits fertig ist, bevor Sie join () aufrufen. Der Hauptthread wird einfach sofort freigegeben, wenn join () aufgerufen wird.
Tatsächlich fällt mir gerade ein, dass der Haupt-Thread bei d.join () wartet, bis Thread d beendet ist, bevor er zu t.join () übergeht.
Um ganz klar zu sein, betrachten Sie diesen Code:
Diese Ausgabe wird erzeugt (beachten Sie, wie die Druckanweisungen ineinander eingefädelt sind.)
Das t1.join () hält den Haupt-Thread hoch. Alle drei Threads werden abgeschlossen, bevor t1.join () beendet wird und der Haupt-Thread fortfährt, um den Druck auszuführen. Dann t2.join (), dann print, dann t3.join () und dann print.
Korrekturen sind willkommen. Ich bin auch neu im Threading.
(Hinweis: Falls Sie interessiert sind, schreibe ich Code für einen DrinkBot und benötige Threading, um die Zutatenpumpen gleichzeitig und nicht nacheinander zu betreiben - weniger Zeit, um auf jedes Getränk zu warten.)
quelle
Die Methode join ()
Quelle: http://docs.python.org/2/library/threading.html
quelle
t.join()
und das Programm wartet immer noch darauf, bevor es beendet wird. Ich sehe keine Verwendung vont.join()
hier in meinem CodeEinfach verstehen,
mit join - Der Interpreter wartet, bis Ihr Prozess abgeschlossen oder beendet ist
ohne Join - Interpreter wird nicht warten, bis der Prozess beendet wird ,
quelle
Wenn die
join(t)
Funktion sowohl für Nicht-Daemon-Threads als auch für Daemon-Threads ausgeführt wird, sollte der Haupt-Thread (oder Hauptprozess)t
Sekunden warten und kann dann weiter an seinem eigenen Prozess arbeiten. Während dert
Wartezeit von Sekunden sollten beide untergeordneten Threads das tun, was sie können, z. B. Text ausdrucken.t
Wenn nach den Sekunden ein Nicht-Daemon-Thread seinen Job immer noch nicht beendet hat und er ihn auch beenden kann, nachdem der Hauptprozess seinen Job beendet hat, hat er für den Daemon-Thread nur das Opportunity-Fenster verpasst. Es wird jedoch irgendwann nach dem Beenden des Python-Programms sterben. Bitte korrigieren Sie mich, wenn etwas nicht stimmt.quelle
In Python 3.x wird join () verwendet, um einen Thread mit dem Hauptthread zu verbinden. Wenn join () für einen bestimmten Thread verwendet wird, wird die Ausführung des Hauptthreads beendet, bis die Ausführung des verknüpften Threads abgeschlossen ist.
quelle
Dieses Beispiel zeigt die
.join()
Aktion:Aus:
quelle
Es gibt einige Gründe, warum der Haupt-Thread (oder ein anderer Thread) andere Threads verbindet
Ein Thread hat möglicherweise einige Ressourcen erstellt oder gehalten (gesperrt). Der Join-Calling-Thread kann möglicherweise die Ressourcen in seinem Namen löschen
join () ist ein natürlicher Blockierungsaufruf für den Join-aufrufenden Thread, der fortgesetzt wird, nachdem der aufgerufene Thread beendet wurde.
Wenn ein Python-Programm keine anderen Threads verbindet, verbindet der Python-Interpreter weiterhin Nicht-Daemon-Threads in seinem Namen.
quelle
"Was nützt die Verwendung von join ()?" du sagst. Wirklich, es ist die gleiche Antwort wie "Was nützt das Schließen von Dateien, da Python und das Betriebssystem meine Datei für mich schließen, wenn mein Programm beendet wird?".
Es ist einfach eine Frage guter Programmierung. Sie sollten Ihre Threads an der Stelle im Code verbinden (), an der der Thread nicht mehr ausgeführt werden soll, entweder weil Sie sicher sein müssen, dass der Thread nicht ausgeführt wird, um Ihren eigenen Code zu stören, oder weil Sie sich in a korrekt verhalten möchten größeres System.
Sie könnten sagen "Ich möchte nicht, dass mein Code die Beantwortung verzögert", nur wegen der zusätzlichen Zeit, die join () möglicherweise benötigt. Dies mag in einigen Szenarien durchaus gültig sein, aber Sie müssen jetzt berücksichtigen, dass Ihr Code "Cruft für Python und das Betriebssystem zur Bereinigung übrig lässt". Wenn Sie dies aus Leistungsgründen tun, empfehle ich Ihnen dringend, dieses Verhalten zu dokumentieren. Dies gilt insbesondere dann, wenn Sie eine Bibliothek / ein Paket erstellen, die / das von anderen erwartet wird.
Es gibt keinen Grund, nicht join (), andere als Performance - Gründe, und ich würde behaupten , dass Ihr Code muss nicht ausführen , dass gut.
quelle
join()
.