Existe-t-il une notion générique de programmation asynchrone en python? Puis-je attribuer un rappel à une fonction, l'exécuter et revenir immédiatement au flux de programme principal, peu importe la durée d'exécution de cette fonction?
Jetez un œil ici:
Programmation asynchrone en Python
ne introduction à la programmation asynchrone et torsadée
Vaut le détour:
asyncio (anciennement Tulip) a été archivé dans la branche Python par défaut
Aujourd'hui Python a asyncIO - E/S asynchrones, boucle d'événements, coroutines et tâches intégré.
Description extraite du lien ci-dessus:
Le module asyncIO fournit une infrastructure pour écrire du code simultané à un seul thread à l'aide de coroutines, multiplexer l'accès aux E/S sur des sockets et d'autres ressources, exécuter des clients et des serveurs réseau, et d'autres primitives apparentées. Voici une liste plus détaillée du contenu du paquet:
- une boucle d'événements enfichable avec diverses implémentations spécifiques au système;
- transport et abstractions de protocole (similaires à ceux de Twisted);
- prise en charge concrète de TCP, UDP, SSL, canaux de sous-processus, appels retardés et autres (certains peuvent dépendre du système);
- une classe Future qui imite celle du module concurrent.futures, mais adaptée pour être utilisée avec la boucle d'événement;
- coroutines et tâches basées sur le rendement de (PEP 380), pour aider à écrire du code simultané de manière séquentielle;
- support d'annulation pour Futures et coroutines;
- primitives de synchronisation à utiliser entre les coroutines d'un même thread, imitant celles du module de thread;
- une interface pour transmettre le travail à un pool de threads, pour les moments où vous devez absolument, positivement, utiliser une bibliothèque qui bloque les appels d'E/S.
La programmation asynchrone est plus complexe que la programmation "séquentielle" classique: voir la page Développer avec asyncio qui répertorie les pièges courants et explique comment les éviter. Activez le mode de débogage pendant le développement pour détecter les problèmes courants.
A voir également:
Ce que vous décrivez (le flux de programme principal reprenant immédiatement pendant qu'une autre fonction s'exécute) n'est pas ce que l'on appelle normalement la programmation "asynchrone" (AKA "événementielle"), mais plutôt "multitâche" (AKA "multithreading" ou "multiprocessing"). Vous pouvez obtenir ce que vous avez décrit avec les modules de bibliothèque standard threading
et multiprocessing
(ce dernier permet une exécution simultanée réelle sur des machines multicœurs).
La programmation asynchrone (pilotée par les événements) est prise en charge dans la bibliothèque standard Python dans les modules asyncore
et asynchat
, qui sont très orientés vers les tâches de mise en réseau (en effet, ils utiliser en interne le module select
, qui, sous Windows, ne prend en charge que les sockets - bien que sur les systèmes d'exploitation Unixy, il puisse également prendre en charge n'importe quel descripteur de fichier).
Pour une prise en charge plus générale (mais aussi principalement orientée réseau, mais pas limitée à cela) de la programmation asynchrone (pilotée par les événements), consultez le - tord package tiers.
Bonnes nouvelles tout le monde!
Python 3.4 inclurait une toute nouvelle programmation asynchrone ambitieuse implémentation !
Il est actuellement appelé tulipe et possède déjà un suivi actif .
Comme décrit dans PEP 3153: asynchrone IO et PEP 3156: asynchrone IO redémarré :
Les personnes qui souhaitent écrire du code asynchrone en Python en ce moment ont quelques options:
- asyncore et asynchat;
- quelque chose sur mesure, très probablement basé sur le module de sélection;
- en utilisant une bibliothèque tierce, telle que Twisted ou gevent .
Malheureusement, chacune de ces options a ses inconvénients, que ce PEP essaie de résoudre.
Bien qu'il fasse partie de la bibliothèque standard Python depuis longtemps, le module asyncore souffre de défauts fondamentaux résultant d'une API inflexible qui ne répond pas aux attentes d'un module de mise en réseau asynchrone moderne.
De plus, son approche est trop simpliste pour fournir aux développeurs tous les outils dont ils ont besoin pour exploiter pleinement le potentiel des réseaux asynchrones.
La solution la plus populaire actuellement utilisée en production implique l'utilisation de bibliothèques tierces. Celles-ci fournissent souvent des solutions satisfaisantes, mais il y a un manque de compatibilité entre ces bibliothèques, ce qui tend à rendre les bases de code très étroitement couplées à la bibliothèque qu'elles utilisent.
Ce manque actuel de portabilité entre les différentes bibliothèques asynchrones IO cause beaucoup d'efforts en double pour les développeurs de bibliothèques tiers. Une abstraction suffisamment puissante pourrait signifier que le code asynchrone est écrit une fois, mais utilisé partout.
Voici le bref aperç de ses capacités.
Les autres répondants vous pointent vers Twisted, qui est un cadre génial et très complet, mais à mon avis, il a un design très non-Pythonic. De plus, AFAICT, vous devez utiliser la boucle principale Twisted, ce qui peut être un problème pour vous si vous utilisez déjà quelque chose d'autre qui fournit sa propre boucle.
Voici un exemple artificiel qui démontrerait l'utilisation du module threading
:
from threading import Thread
def background_stuff():
while True:
print "I am doing some stuff"
t = Thread(target=background_stuff)
t.start()
# Continue doing some other stuff now
Cependant, dans presque tous les cas utiles, vous souhaiterez communiquer entre les threads. Vous devriez examiner primitives de synchronisation , et vous familiariser avec le concept de simultanéité et les problèmes associés.
Le module threading
fournit de nombreuses primitives de ce type que vous pouvez utiliser, si vous savez comment les utiliser.
Vous voudrez peut-être vérifier la bibliothèque Twisted pour Python. Ils fournissent de nombreux outils utiles.
Vous pouvez voir mon Python Outil de programmation asynchrone: http://www.ideawu.com/blog/2010/08/delegate-in-pythonpython-asynchronous-programming.html
import time, random, sys from delegate import * def proc (a): time.sleep (random.random () ) return str (a) def proc_callback (handle, args = None): ret = d.end (handle) d = Délégué () d.init (2) # nombre de travailleurs handle = d.begin (proc, '12345', proc_callback, 'test ') sys.stdin.readline () d.free ()