Pourquoi ne puis-je pas attraper SIGINT lorsque la boucle d’événement asyncio est en cours d’exécution?

En utilisant Python 3.4.1 sur Windows, j’ai constaté que lors de l’exécution d’une boucle d’événement asyncio , mon programme ne peut pas être interrompu (en appuyant sur Ctrl + C dans le terminal). Plus précisément, le signal SIGINT est ignoré. À l’inverse, j’ai déterminé que SIGINT est géré lorsqu’il n’est pas dans une boucle d’événement.

Pourquoi est-ce que SIGINT est ignoré lors de l’exécution d’une boucle d’événement asyncio?

Le programme ci-dessous doit démontrer le problème – lancez-le dans le terminal et essayez de l’arrêter en appuyant sur Ctrl + C, il devrait continuer à fonctionner:

import asyncio import signal # Never gets called after entering event loop def handler(*args): print('Signaled') signal.signal(signal.SIGINT, handler) print('Event loop starting') loop = asyncio.SelectorEventLoop() asyncio.set_event_loop(loop) loop.run_forever() print('Event loop ended') 

Voir la discussion sur la liste de diffusion officielle (Tulip).

    J’ai trouvé une solution de rechange, qui consiste à planifier un rappel périodique. Pendant ce temps, SIGINT est apparemment traité:

     import asyncio def wakeup(): # Call again loop.call_later(0.1, wakeup) print('Event loop starting') loop = asyncio.SelectorEventLoop() # Register periodic callback loop.call_later(0.1, wakeup) asyncio.set_event_loop(loop) loop.run_forever() print('Event loop ended') 

    Vous ne savez pas pourquoi cela est nécessaire, mais cela indique que les signaux sont bloqués pendant que la boucle d’événement attend des événements (“sondages”).

    La question a été discutée sur la liste de diffusion officielle (Tulip), ma solution de contournement est apparemment la voie à suivre maintenant.

    Mettre à jour

    Un correctif est supposé avoir pénétré dans Python 3.5 . J’espère donc que cette solution Python rendra obsolète ma solution.

    J’ai constaté que lors de l’exécution d’une boucle d’événement asyncio, mon programme ne peut pas être interrompu (en appuyant sur Ctrl + C dans le terminal)

    Pour clarifier: ctrl-C peut ne pas fonctionner, mais ctrl-break fonctionne correctement.

    Normalement, vous appendiez un callback avec loop.add_signal_handler() mais, malheureusement, cette fonctionnalité n’est malheureusement pas prise en charge avec les boucles d’événement Windows intégrées: /

    Une vérification périodique pourrait être utilisée, oui. Sinon, la boucle s’exécute en dehors de la capacité du module de signal à piéger les signaux.