Maison  >  Article  >  développement back-end  >  Explication détaillée de la façon d'utiliser les objets coroutine et les objets Future dans asyncio

Explication détaillée de la façon d'utiliser les objets coroutine et les objets Future dans asyncio

高洛峰
高洛峰original
2017-03-28 15:28:172878parcourir

asyncio est une bibliothèque standard introduite dans Python version 3.4, avec prise en charge intégrée des E/S asynchrones. Le modèle de programmation d'asyncio est uneboucle de message. Aujourd'hui, nous allons discuter en détail de la relation entre la coroutine et les objets Futuredans asyncio

">

coroutine et Future

Il semble que les deux soient de même, car la syntaxe suivante peut être utilisée pour obtenir des résultats de manière asynchrone,

result = await future
result = await coroutine

En fait, la coroutine est une générateurfonction, qui peut être obtenue à partir de Des paramètres externes peuvent également être générés. L'avantage de l'utilisation de la coroutine est que nous pouvons suspendre une fonction puis reprendre l'exécution plus tard. Par exemple, lorsque des opérations réseau sont impliquées, la fonction peut être arrêtée jusqu'à ce que la réponse arrive. passez à d'autres tâches pour continuer l'exécution.

Et Future ressemble plus à un objet Promise en Javascript C'est un espace réservé dont la valeur sera modifiée dans le futur. Par exemple, lorsque nous attendons la fin de la fonction réseau IO, la fonction nous donnera un conteneur, et la promesse remplira le conteneur une fois terminé, et nous pourrons utiliser la fonction de rappel pour obtenir. les résultats réels.

L'objet Task est une sous-classe de Future, qui connecte la coroutine et Future, et encapsule la coroutine dans un objet Future

Généralement, vous verrez deux types de tâches démarrées. ,

tasks = asyncio.gather(
  asyncio.ensure_future(func1()),
  asyncio.ensure_future(func2())
)
loop.run_until_complete(tasks)

et

tasks = [
  asyncio.ensure_future(func1()),
  asyncio.ensure_future(func2())
  ]
loop.run_until_complete(asyncio.wait(tasks))

ensure_future peuvent encapsuler des coroutines dans des tâches asyncio.gather encapsule certains Futures et coroutines dans une Future wait elle-même est une coroutine. >run_until_complete peut recevoir soit un objet Future, soit un objet coroutine

La bonne

sortie

de la tâche Task
BaseEventLoop.run_until_complete(future)
Run until the Future is done.
If the argument is a coroutine object, it is wrapped by ensure_future().
Return the Future's result, or raise its exception.

Dans la boucle de tâche asyncio, si vous utilisez CTRL-C pour quitter, même si l'exception est interceptée, la tâche dans la boucle d'événements signalera une erreur et l'erreur suivante apparaîtra, La tâche a été détruite mais elle est en attente !

tâche : wait_

for

=> ;


Selon la documentation officielle, l'objet Task sera considéré comme sorti uniquement dans les situations suivantes : un résultat/exception est disponible, ou que le futur a été annulé

Le L'annulation de l'objet tâche est légèrement différente de sa classe parent, Future. Lorsque Task.cancel() est appelé, la coroutine correspondante lèvera une exception CancelledError au prochain tour de la boucle

event

. L'utilisation de Future.cancelled() ne renvoie pas True immédiatement (utilisé pour indiquer la fin de la tâche). Elle n'est considérée comme annulée qu'une fois l'exception ci-dessus traitée et la tâche terminée.

Donc, pour terminer la tâche, vous pouvez utiliser

pour retrouver toutes les tâches et les annuler.

Mais CTRL-C arrêtera également la boucle d'événements, il est donc nécessaire de redémarrer la boucle d'événements
for task in asyncio.Task.all_tasks():
  task.cancel()

Il est nécessaire d'intercepter les exceptions dans chaque tâche. bien sûr, vous pouvez utiliser

asyncio.gather(..., return_exceptions=True)
try:
  loop.run_until_complete(tasks)
except KeyboardInterrupt as e:
  for task in asyncio.Task.all_tasks():
    task.cancel()
  loop.run_forever() # restart loop
finally:
  loop.close()

Convertir les exceptions en résultats normaux et les renvoyer.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn