Seite 1 von 1

sys.exit und Threads

Verfasst: Donnerstag 15. März 2007, 10:02
von antaeus
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 :-)

Re: sys.exit und Threads

Verfasst: Donnerstag 15. März 2007, 10:25
von gerold
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
:-)

Verfasst: Donnerstag 15. März 2007, 10:30
von BlackJack
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()`).