Parfois, il y a une opération asynchrone non critique qui doit se produire, mais je ne veux pas attendre qu'elle se termine. Dans l'implémentation coroutine de Tornado, vous pouvez "déclencher et oublier" une fonction asynchrone en ôtant simplement le yield
mot-clé.
J'ai essayé de comprendre comment "tirer et oublier" avec la nouvelle syntaxe async
/ await
publiée dans Python 3.5. Par exemple, un extrait de code simplifié:
async def async_foo():
print("Do some stuff asynchronously here...")
def bar():
async_foo() # fire and forget "async_foo()"
bar()
Ce qui se passe cependant, c'est que cela bar()
ne s'exécute jamais et à la place, nous obtenons un avertissement d'exécution:
RuntimeWarning: coroutine 'async_foo' was never awaited
async_foo() # fire and forget "async_foo()"
python
python-3.5
python-asyncio
Mike N
la source
la source
Réponses:
Actualiser:
Remplacez
asyncio.ensure_future
parasyncio.create_task
partout si vous utilisez Python> = 3.7 C'est un moyen plus récent et plus agréable de générer une tâche .asyncio.Tâche de "tirer et oublier"
Selon la documentation de python,
asyncio.Task
il est possible de démarrer une coroutine à exécuter "en arrière-plan" . La tâche créée parasyncio.ensure_future
function ne bloquera pas l'exécution (donc la fonction retournera immédiatement!). Cela ressemble à un moyen de «tirer et d'oublier» comme vous l'avez demandé.Production:
Que faire si les tâches s'exécutent après la fin de la boucle d'événements?
Notez qu'asyncio s'attend à ce que la tâche soit terminée au moment où la boucle d'événements est terminée. Donc, si vous changez
main()
pour:Vous recevrez cet avertissement une fois le programme terminé:
Pour éviter cela, vous pouvez simplement attendre toutes les tâches en attente une fois la boucle d'événements terminée:
Tuez les tâches au lieu de les attendre
Parfois, vous ne voulez pas attendre que les tâches soient terminées (par exemple, certaines tâches peuvent être créées pour s'exécuter indéfiniment). Dans ce cas, vous pouvez simplement les annuler () au lieu de les attendre:
Production:
la source
stop()
méthode.Merci Sergey pour la réponse succincte. Voici la version décorée de la même chose.
Produit
Remarque: Vérifiez mon autre réponse qui fait la même chose en utilisant des fils simples.
la source
Ce n'est pas une exécution entièrement asynchrone, mais peut-être que run_in_executor () vous convient.
la source
executor
volonté par défaut d'appelerconcurrent.futures.ThreadPoolExecutor.submit()
. Je mentionne parce que la création de fils n'est pas gratuite; le feu et l'oubli 1000 fois par seconde mettra probablement une grosse pression sur la gestion des threadsPour une raison quelconque, si vous ne pouvez pas utiliser,
asyncio
voici l'implémentation utilisant des threads simples. Vérifiez mes autres réponses et la réponse de Sergey aussi.la source