sys.exit und Threads

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
antaeus
User
Beiträge: 48
Registriert: Dienstag 19. September 2006, 10:10

Donnerstag 15. März 2007, 10:02

Ich habe eine Verständnisfrage: Ich dachte bisher, dass wenn ich an einer beliebigen Stelle eines Programms (welches ggf. Threads enthält) sys.exit ausführe, dass dann das ganze Programm samt Threads beendet werden würde. Ist aber nicht so.

Wenn z.B. ein Thread an einer Stelle blockiert (z.B. weil er auf neue Daten aus einer Queue.queue oder von einem Socket wartet) beendet sich das Programm deswegen scheinbar NICHT.

Ist das Verhalten so korrekt, oder habe ich da irgendeinen Fehler gemacht?

Gibt es ferner den ultimativen, finalen Rettungsschuss-Befehl für ein Programm mit Threads? Also: einmal ausgeführt; Alle Threads tot :-)
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Donnerstag 15. März 2007, 10:25

antaeus hat geschrieben:Gibt es ferner den ultimativen, finalen Rettungsschuss-Befehl für ein Programm mit Threads? Also: einmal ausgeführt; Alle Threads tot :-)
Hallo antaeus!

Nein, gibt es nicht. Threads verhalten sich in dieser Hinsicht je nach Betriebssystem und Servicepack anders. Die einzig sichere Lösung ist, in jeden Thread eine Methode einzubauen, die sich darum kümmert, dass der Thread abgebrochen/geschlossen wird.

Und um diesen Mechanismus auch korrekt ausnutzen zu können, musst du dich auch darum kümmern, dass das Programm nicht beendet wird, ohne auf die Beendung der Threads zu warten.

Das ist zwar nicht einfach, aber die einzige saubere Lösung. Das ist auch einer der Gründe dafür, dass die Programmierung mit Threads nicht einfach ist.

Ich demonstrier das mal:

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: iso-8859-1 -*-

import threading
import time


class MyThread(threading.Thread):
    
    def __init__(self, label):
        
        threading.Thread.__init__(self)
        self.cancel_event = threading.Event()
        self.label = label
    
    
    def run(self):
        
        while not self.cancel_event.isSet():
            print "im Threadrunner '%s'" % self.label
            time.sleep(1)
    
    
    def stop(self):
        
        self.cancel_event.set()


def main():
    
    t1 = MyThread("t1")
    t2 = MyThread("t2")
    
    t1.start()
    t2.start()
    
    time.sleep(10)
    
    t1.stop()
    t2.stop()
    
    # Warten, bis die Threads beendet wurden
    t1.join()
    t2.join()
    
    print "Fertig"


if __name__ == "__main__":
    main()
mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
BlackJack

Donnerstag 15. März 2007, 10:30

Das Verhalten ist korrekt. Wenn Du nicht möchtest, dass aktive Threads Dein Programm am "Leben" erhalten, musst Du sie zu "daemonic" Threads machen (`Thread.setDaemon()`).
Antworten