Ich denke, es ist am besten, join()
anzurufen an deinen Fäden, wenn du erwartest, dass sie sterben. Ich habe mir die Freiheit genommen, Ihre Schleifen so zu ändern, dass sie enden (Sie können dort auch alle erforderlichen Bereinigungsanforderungen hinzufügen). Die Variable die
wird bei jedem Durchlauf überprüft und wenn es True
ist , das Programm wird beendet.
import threading
import time
class MyThread (threading.Thread):
die = False
def __init__(self, name):
threading.Thread.__init__(self)
self.name = name
def run (self):
while not self.die:
time.sleep(1)
print (self.name)
def join(self):
self.die = True
super().join()
if __name__ == '__main__':
f = MyThread('first')
f.start()
s = MyThread('second')
s.start()
try:
while True:
time.sleep(2)
except KeyboardInterrupt:
f.join()
s.join()
KeyboardInterrupt und Signale werden nur vom Prozess (dh dem Hauptthread) gesehen ... Schauen Sie sich Ctrl-c an, dh KeyboardInterrupt, um Threads in Python zu beenden
Strg +C beendet den Haupt-Thread, aber da sich Ihre Threads nicht im Daemon-Modus befinden, laufen sie weiter, und das hält den Prozess am Leben. Wir können sie zu Dämonen machen:
f = FirstThread()
f.daemon = True
f.start()
s = SecondThread()
s.daemon = True
s.start()
Aber dann gibt es noch ein weiteres Problem - sobald der Haupt-Thread Ihre Threads gestartet hat, gibt es für ihn nichts weiter zu tun. Es wird also beendet und die Threads werden sofort zerstört. Lassen Sie uns also den Hauptthread am Leben erhalten:
import time
while True:
time.sleep(1)
Jetzt wird es 'erste' und 'zweite' drucken, bis Sie Strg drücken +C .
Bearbeiten: Wie Kommentatoren darauf hingewiesen haben, haben die Daemon-Threads möglicherweise keine Chance, Dinge wie temporäre Dateien zu bereinigen. Wenn Sie das brauchen, dann fangen Sie die KeyboardInterrupt
auf dem Haupt-Thread und lassen Sie ihn die Bereinigung und das Herunterfahren koordinieren. Aber in vielen Fällen reicht es wahrscheinlich aus, Daemon-Threads plötzlich sterben zu lassen.
Eine verbesserte Version der Antwort von @Thomas K:
- Assistentenfunktion definieren
is_any_thread_alive()
nach dieser Kernaussage, die denmain()
beenden kann automatisch.
Beispielcodes:
import threading
def job1():
...
def job2():
...
def is_any_thread_alive(threads):
return True in [t.is_alive() for t in threads]
if __name__ == "__main__":
...
t1 = threading.Thread(target=job1,daemon=True)
t2 = threading.Thread(target=job2,daemon=True)
t1.start()
t2.start()
while is_any_thread_alive([t1,t2]):
time.sleep(0)