Exécuteurs (runners)¶
Code source : Lib/asyncio/runners.py
Cette section décrit les primitives asyncio de haut niveau pour exécuter du code asynchrone.
Elles sont construites au-dessus d'une boucle d'événements dans le but de simplifier l'utilisation du code asynchrone pour les scénarios les plus courants.
Exécution d'un programme asynchrone¶
- asyncio.run(coro, *, debug=None, loop_factory=None)¶
Execute coro in an asyncio event loop and return the result.
The argument can be any awaitable object.
This function runs the awaitable, taking care of managing the asyncio event loop, finalizing asynchronous generators, and closing the executor.
Cette fonction ne peut pas être appelée lorsqu'une autre boucle d'événement asynchrone est en cours d'exécution dans le même fil d'exécution.
Si debug vaut
True
, la boucle d'événements est exécutée en mode débogage.False
désactive explicitement le mode débogage.None
est utilisée pour respecter les paramètres globaux définis par Mode débogage.If loop_factory is not
None
, it is used to create a new event loop; otherwiseasyncio.new_event_loop()
is used. The loop is closed at the end. This function should be used as a main entry point for asyncio programs, and should ideally only be called once. It is recommended to use loop_factory to configure the event loop instead of policies. Passingasyncio.EventLoop
allows running asyncio without the policy system.The executor is given a timeout duration of 5 minutes to shutdown. If the executor hasn't finished within that duration, a warning is emitted and the executor is closed.
Exemple :
async def main(): await asyncio.sleep(1) print('hello') asyncio.run(main())
Ajouté dans la version 3.7.
Modifié dans la version 3.9: mise à jour pour utiliser
loop.shutdown_default_executor()
.Modifié dans la version 3.10: debug vaut
None
par défaut pour respecter les paramètres du mode de débogage global.Modifié dans la version 3.12: Added loop_factory parameter.
Modifié dans la version 3.14: coro can be any awaitable object.
Gestionnaire de contexte de l'exécuteur¶
- class asyncio.Runner(*, debug=None, loop_factory=None)¶
Gestionnaire de contexte englobant plusieurs appels de fonctions asynchrones dans le même contexte.
Parfois, plusieurs fonctions asynchrones de niveau supérieur doivent être appelées dans la même boucle d'événements et le même
contextvars.Context
.Si debug vaut
True
, la boucle d'événements est exécutée en mode débogage.False
désactive explicitement le mode débogage.None
est utilisée pour respecter les paramètres globaux définis par Mode débogage.loop_factory peut être utilisée pour remplacer la création de la boucle. loop_factory a la responsabilité de définir la boucle créée comme boucle courante. Par défaut
asyncio.new_event_loop()
est utilisée et définie comme boucle d'événements actuelle avecasyncio.set_event_loop()
si loop_factory vautNone
.Basically,
asyncio.run()
example can be rewritten with the runner usage:async def main(): await asyncio.sleep(1) print('hello') with asyncio.Runner() as runner: runner.run(main())
Ajouté dans la version 3.11.
- run(coro, *, context=None)¶
Execute coro in the embedded event loop.
The argument can be any awaitable object.
If the argument is a coroutine, it is wrapped in a Task.
An optional keyword-only context argument allows specifying a custom
contextvars.Context
for the code to run in. The runner's default context is used if context isNone
.Returns the awaitable's result or raises an exception.
Cette fonction ne peut pas être appelée lorsqu'une autre boucle d'événement asynchrone est en cours d'exécution dans le même fil d'exécution.
Modifié dans la version 3.14: coro can be any awaitable object.
- close()¶
Termine l'exécuteur.
Finalise les générateurs asynchrones, arrête l'exécuteur par défaut, ferme la boucle d'événements et libère le
contextvars.Context
en cours.
- get_loop()¶
Renvoie la boucle d'événements associée à l'instance de l'exécuteur.
Note
Runner
utilise la stratégie d'initialisation paresseuse, son constructeur n'initialise pas les structures de bas niveau sous-jacentes.La boucle d'événements loop et le context intégrés sont créés à l'entrée du corps de
with
ou au premier appel derun()
ouget_loop()
.
Gestion de l'interruption par le clavier¶
Ajouté dans la version 3.11.
Lorsque signal.SIGINT
est déclenché par Ctrl-C, l'exception KeyboardInterrupt
est levée par défaut dans le fils d'exécution principal. Cependant, cela ne fonctionne pas avec asyncio
car cela peut interrompre le fonctionnement interne de asyncio et empêcher le programme de se terminer.
Pour contrer ce problème, asyncio
gère signal.SIGINT
comme suit :
asyncio.Runner.run()
installe un gestionnairesignal.SIGINT
personnalisé avant l'exécution de tout code utilisateur et le supprime à la sortie de la fonction.Le
Runner
crée la tâche principale pour la coroutine transmise pour son exécution.Lorsque
signal.SIGINT
est déclenché par Ctrl-C, le gestionnaire de signal personnalisé annule la tâche principale en appelantasyncio.Task.cancel()
qui lèveasyncio.CancelledError
à l'intérieur de la tâche principale. Cela entraîne la remontée dans la pile Python, les blocstry/except
ettry/finally
peuvent être utilisés pour le nettoyage des ressources. Une fois la tâche principale annulée,asyncio.Runner.run()
lèveKeyboardInterrupt
.Un utilisateur peut écrire une boucle tellement petite qu'elle ne peut pas être interrompue par
asyncio.Task.cancel()
; dans ce cas la seconde suivante Ctrl-C lève immédiatement leKeyboardInterrupt
sans annuler la tâche principale.