Ich habe einen Web-Crawler geschrieben, den ich gerne über die Tastatur anhalten könnte. Ich möchte nicht, dass das Programm stirbt, wenn ich es unterbreche; Es muss zuerst seine Daten auf der Festplatte löschen. Ich möchte auch KeyboardInterruptedException
nicht abfangen, da die persistenten Daten in einem inkonsistenten Zustand sein könnten.
Meine aktuelle Lösung besteht darin, einen Signal-Handler zu definieren, der SIGINT
abfängt und ein Flag setzt; Jede Iteration der Hauptschleife prüft dieses Flag vor der Verarbeitung der nächsten URL.
Ich habe jedoch festgestellt, dass wenn das System socket.recv()
ausführt, wenn ich den Interrupt sende, bekomme ich folgendes:
und der Prozess wird vollständig beendet. Warum passiert das? Kann ich verhindern, dass der Interrupt den Systemaufruf beeinflusst?
socket.recv()
ruft die zugrunde liegende POSIX-kompatible Funktion recv
in der C-Schicht auf, die wiederum den Fehlercode EINTR
zurückgibt, wenn der Prozess eine SIGINT
empfängt, während er auf eingehende Daten in% co_de wartet %. Dieser Fehlercode kann auf der C-Seite verwendet werden (wenn Sie in C programmiert haben), um zu erkennen, dass recv()
nicht zurückgegeben wurde, weil mehr Daten auf dem Socket verfügbar sind, sondern weil der Prozess eine recv()
erhalten hat. Wie auch immer, dieser Fehlercode wird von Python in eine Ausnahme umgewandelt, und da er nie abgefangen wird, beendet er Ihre Anwendung mit dem Traceback, den Sie sehen. Die Lösung besteht einfach darin, SIGINT
abzufangen, den Fehlercode zu überprüfen, und wenn er gleich socket.error
ist, ignoriere die Ausnahme stillschweigend. Etwas wie das:
Wenn Ihr Socket-Aufruf nicht unterbrochen werden soll, deaktivieren Sie das Interrupt-Verhalten, nachdem Sie den Signal-Handler gesetzt haben.
%Vor%In der Signalbehandlungsfunktion wird ein Flag gesetzt, z. a threading.Event () und dann dieses Flag in Ihrer Hauptverarbeitungsfunktion überprüfen und Ihren Crawler ordnungsgemäß beenden.
Hintergrundinformationen hier:
Tags und Links python signals system-calls unix interrupt