Ich habe eine sehr einfache Python-Klasse geschrieben, die auf Verbindungen auf einem Socket wartet. Die Absicht ist, diese Klasse in eine bestehende App zu stecken und asynchron Daten an verbindende Clients zu senden.
Das Problem ist, dass wenn ich auf ein socket.accept () warte, kann ich meine Anwendung nicht beenden, indem ich ctrl-c drücke. Ich kann auch nicht erkennen, wenn meine Klasse den Rahmen verlässt und sie zum Ende benachrichtigen.
Idealerweise sollte die Anwendung unten beendet werden, nachdem time.sleep (4) abgelaufen ist. Wie Sie unten sehen können, habe ich versucht, select zu verwenden, aber dies verhindert auch, dass die App auf ctrl-c reagiert. Wenn ich feststellen könnte, dass die Variable 'a' in der Hauptmethode den Gültigkeitsbereich verlassen hat, könnte ich das Beendigungsflag setzen (und das Zeitlimit bei Auswahl reduzieren, um darauf zu reagieren).
Irgendwelche Ideen?
Danke
%Vor% Fügen Sie self.setDaemon(True)
zu __init__
vor self.start()
hinzu.
(In Python 2.6 und höher wird self.daemon = True
bevorzugt).
Die Schlüsselidee ist hier erklärt:
Das gesamte Python-Programm wird beendet, wenn Es sind keine lebendigen Nicht-Daemon-Threads übrig.
Man muss also "Dämonen" jener Fäden machen, die den ganzen Prozess nicht am Leben erhalten sollen, nur indem sie selbst am Leben sind. Der Hauptthread ist übrigens immer ein Nicht-Daemon.
Ich empfehle die Funktion setDaemon nicht zum normalen Herunterfahren. Es ist schlampig; Anstatt einen sauberen Abschaltpfad für Threads zu haben, wird der Thread einfach beendet, ohne dass eine Bereinigung möglich ist. Es ist gut, es einzustellen, damit Ihr Programm nicht hängenbleibt, wenn der Hauptthread unerwartet beendet wird, aber es ist kein guter normaler Abschaltpfad außer für schnelle Hacks.
%Vor%Beachten Sie, dass dies bis zu einer Sekunde nach dem Aufruf von shutdown () verzögert wird, was ein schlechtes Verhalten ist. Dies ist normalerweise einfach zu beheben: Erstellen Sie eine Wakeup-Pipe (), in die Sie schreiben können, und fügen Sie sie in die Auswahl ein; Obwohl dies sehr einfach ist, konnte ich in Python keine Möglichkeit finden, dies zu tun. (os.pipe () gibt Dateideskriptoren zurück, keine Dateiobjekte, auf die wir schreiben können.) Ich habe nicht tiefer gegraben, da es sich um die Frage handelt.