concurrent.futures
http://docs.python.jp/3/library/concurrent.futures.html
Un nouveau package standard dans Python 3.2 qui facilite l'implémentation d'un traitement de tâches parallèle multi-thread et multi-processus.
ThreadPoolExecutor et ProcessPoolExecutor sont implémentés en héritant de la classe de base appelée Executor, et vous pouvez écrire avec presque la même interface en utilisant l'un ou l'autre.
Puisqu'il s'agit d'un package standard en Python 3.2, il n'est pas nécessaire de l'installer. Backport est disponible pour les versions 2.6 et supérieures.
python
pip install futures
import concurrent.futures
import hashlib
def digest(t): #Fonction pour consommer les ressources du processeur de manière appropriée
hash = hashlib.sha256()
for i in range(t*1000000):
hash.update('hogehoge')
return hash.hexdigest()
if __name__=='__main__':
task_list = [1,1,1,2,2,3]
#Créer un objet Executor
executor = concurrent.futures.ProcessPoolExecutor(max_workers=4)
#Soumettez la tâche à l'objet Executor et obtenez le même nombre d'objets futurs.
#L'exécution de la tâche est soumise()Cela commence à partir du moment où vous appelez.
futures = [executor.submit(digest,t) for t in task_list]
#Attendez la fin de chaque futur et obtenez le résultat.
# as_completed()Renvoie un itérateur qui parcourt les éléments des futurs donnés dans l'ordre d'achèvement.
#Si aucune tâche n'est terminée, elle sera bloquée jusqu'à ce qu'une tâche soit terminée.
for future in concurrent.futures.as_completed(futures):
print(future.result()) # digest()La valeur de retour de s'affiche.
#Attendez que toutes les tâches soient terminées et nettoyées.
#Toutes les tâches non terminées seront bloquées.
# (Un fils_Puisque nous répétons tout terminé, il ne devrait pas y avoir de tâches qui n'ont pas été terminées à ce stade.)
executor.shutdown()
Si vous remplacez ProcessPoolExecutor
par ThreadPoolExecutor
, il fonctionnera en multi-thread au lieu de multi-processus.
ProcessPoolExecutor est réalisé par communication inter-processus, il existe donc certaines restrictions.
Les arguments de fonction et les valeurs de retour doivent être des objets qui peuvent être sérialisés à l'aide de pickle.
La fonction elle-même doit également être transmise entre les processus. Aucune méthode d'instance. Le type Lambda est OK.
Même si la variable globale est réécrite comme un effet secondaire dans la fonction, elle ne sera pas reflétée dans le processus appelant.
CPython implémente Global Interpreter Lock, de sorte que plusieurs threads ne peuvent pas exécuter du code Python en même temps dans un processus. Dans le cas d'une tâche qui exécute du code Python comme l'exemple de code ci-dessus, même si elle est parallélisée avec ThreadPoolExecutor, il s'agira d'un traitement presque séquentiel, il n'y a donc pas beaucoup d'avantages du temps d'exécution. (Il est efficace pour le traitement avec beaucoup d'attente de communication et d'attente d'E / S.)
Recommended Posts