Multitraitement piscine apply_async' semble que la fonction d'appel d'une fois
J'ai suivi la doc pour essayer de comprendre le traitement multiple des piscines. Je suis venu avec cette:
import time
from multiprocessing import Pool
def f(a):
print 'f(' + str(a) + ')'
return True
t = time.time()
pool = Pool(processes=10)
result = pool.apply_async(f, (1,))
print result.get()
pool.close()
print ' [i] Time elapsed ' + str(time.time() - t)
Je suis en train d'utiliser 10 des processus pour évaluer la fonction f(a)
. J'ai mis une instruction print dans f
.
C'est le résultat que j'obtiens:
$ python pooltest.py
f(1)
True
[i] Time elapsed 0.0270888805389
Il me semble que la fonction f
est seulement évaluée une fois.
Je suis susceptible de ne pas utiliser la bonne méthode, mais le résultat final, je suis à la recherche d'consiste à exécuter f
avec 10 processus simultanément, et obtenir le résultat retourné par chacun de ces processus. Donc, je voudrais terminer avec une liste de 10 résultats (qui peuvent ou peuvent ne pas être identiques).
Docs sur le multitraitement sont assez confus et il n'est pas trivial de comprendre que l'approche que je devrais prendre, et il me semble que f
doit être exécuté 10 fois dans l'exemple que j'ai fourni ci-dessus.
Entendu, merci pour la clarification. Serait la meilleure méthode pour
for
boucle de 10 appels ou est-il plus approprié de l'outil dans le multiprocessing
module pour ce que je suis en train de réaliser?Vous souhaitez faire appel de la fonction avec les mêmes arguments à chaque fois?
Oui, il est 10 fois les mêmes arguments. La fonction dépend d'autres vars extrait de la net donc le résultat peut être différent à chaque fois.
Ah, si vous avez des fonctions différentes à chaque fois? Ensuite, vous avez une liste de fonctions, et que vous appelez "appliquer cette fonction de" un tas de fois. OK
OriginalL'auteur Juicy | 2015-02-09
Vous devez vous connecter pour publier un commentaire.
apply_async n'est pas destiné à lancer plusieurs processus; il a simplement pour but d'appeler la fonction avec les arguments de l'un des processus de la piscine. Vous aurez besoin de faire 10 appels si vous voulez que la fonction à appeler 10 fois.
Tout d'abord, notez les docs sur
apply()
(italiques ajoutés):Maintenant, dans les docs pour
apply_async()
:La différence entre les deux est juste que apply_async retourne immédiatement. Vous pouvez utiliser
map()
pour appeler une fonction à plusieurs reprises, mais si vous appelez, avec les mêmes entrées, alors c'est un peu devenus inutiles pour créer la liste de la même argument juste pour avoir une séquence de la bonne longueur.Toutefois, si vous êtes d'appel des différentes fonctions avec le même d'entrée, alors vous êtes vraiment juste appeler un ordre supérieur de la fonction, et vous pourriez le faire avec
map
oumap_async()
comme ceci:sauf que les lambda fonctions ne sont pas pickleable, de sorte que vous aurez besoin d'utiliser une fonction définie (voir Comment laisser de la Piscine.carte prendre une fonction lambda). Vous pouvez réellement utiliser les builtin
apply()
(pas le multitraitement un) (même si c'est déconseillé):Il est assez facile d'écrire votre propre, trop:
lambda
fonctionne comme lambda fonctions ne sont pas pickleable (IIRC).Je comprends comment
apply
fonctionne maintenant et il fait depuis, mais vous avez bien fait la première fois. J'essaie de l'exécuter 10 fois pour la fonction argument (même si le résultat peut ne pas toujours être la même pour d'autres raisons). Je voudrais terminer avec une liste de 10 résultats. Est la meilleure façon de le faire avec unfor
boucle alors?Je pense que carte est ce que vous voulez
Mais
map
semble être la seule à prendre uniterable
, je suppose que je devrais juste faire un objet iterable liste avec les 10 fois le même argument alors.Voir mon jour; vous avez une liste de fonctions; c'est l'objet iterable que vous devez passer. La fonction que vous êtes à la cartographie doit son argument avec le arglist
OriginalL'auteur Joshua Taylor
Chaque fois que vous écrivez
pool.apply_async(...)
il va déléguer cette fonction à appeler à l'un des processus qui a commencé dans la piscine. Si vous voulez appeler la fonction dans plusieurs processus, vous devez émettre plusieurspool.apply_async
appels.Remarque, il existe aussi un
de la piscine.map
(etde la piscine.map_async
) qui permet de prendre une fonction et un objet iterable entrées:Ces fonctions s'appliquent à la fonction de chaque entrée dans le
inputs
itératif. Il tente de se mettre en "lots" dans la piscine de sorte que la charge devient équilibré de manière assez homogène entre tous les processus dans la piscine.OriginalL'auteur mgilson
Si vous souhaitez exécuter un seul morceau de code dans dix processus, chaque de ce qui sort, un
Pool
de dix processus est probablement pas la bonne chose à utiliser.Au lieu de cela, la création de dix
Process
es pour exécuter le code:La
multiprocessing.Pool
classe est conçu pour gérer les situations où le nombre de processus et le nombre d'emplois ne sont pas liés. Souvent le nombre de processus est sélectionné pour être le nombre de cœurs de PROCESSEUR que vous avez, alors que le nombre d'emplois est beaucoup plus grande. Merci!OriginalL'auteur Blckknght
Si vous n'êtes pas engagé à la Piscine pour une raison particulière, j'ai écrit une fonction autour de multitraitement.Processus qui va probablement faire l'affaire pour vous. Il est affiché ici, mais je serais heureux de télécharger la version la plus récente de github si vous le souhaitez.
OriginalL'auteur Steve Bond