J'ai écrit un moteur de balayage Web que j'aimerais pouvoir arrêter via le clavier. Je ne veux pas que le programme meure quand je l'interromps; il doit d'abord vider ses données sur le disque. Je ne veux pas non plus attraper KeyboardInterruptedException
, car les données persistantes pourraient être dans un état incohérent.Attraper/bloquer SIGINT lors de l'appel système
Ma solution actuelle est de définir un gestionnaire de signal qui attrape SIGINT
et définit un drapeau; Chaque itération de la boucle principale vérifie ce drapeau avant de traiter l'URL suivante.
Cependant, j'ai trouvé que si le système arrive à être exécuter socket.recv()
quand j'envoie l'interruption, je reçois ceci:
^C
Interrupted; stopping... // indicates my interrupt handler ran
Traceback (most recent call last):
File "crawler_test.py", line 154, in <module>
main()
...
File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/socket.py", line 397, in readline
data = recv(1)
socket.error: [Errno 4] Interrupted system call
et le processus complètement sorti. Pourquoi cela arrive-t-il? Est-il possible d'empêcher l'interruption d'affecter l'appel système?
Grande explication, je vous remercie. – danben
L'utilisation du nombre magique 4 à la place de 'EINTR' ou de tout identifiant fourni par Python est une très mauvaise pratique. Il est susceptible de casser certaines arches. –
Bien sûr, vous avez raison. J'ai encore lu les docs de la bibliothèque Python et il semble que le module 'errno' fournisse ces constantes, donc je vais ajuster l'exemple. –