2017-07-04 2 views
0

Salut J'essaie d'utiliser le multitraitement pour accélérer mon code. Cependant, le apply_async ne fonctionne pas pour moi. J'ai essayé de faire un exemple simple comme:Python - apply_async n'exécute pas la fonction

from multiprocessing.pool import Pool 
t = [0, 1, 2, 3, 4, 5] 
def cube(x): 
    t[x] = x**3 
pool = Pool(processes=4) 
for i in range(6): 
    pool.apply_async(cube, args=(i,)) 
for x in t: 
    print(x) 

Il ne change pas vraiment t que je me attends.

Mon code réel est comme:

from multiprocessing.pool import Pool 
def func(a, b, c, d): 
    #some calculations 
    #save result to files 
    #no return value 
lt = #list of possible value of a 
#set values to b, c, d 
p = Pool() 
for i in lt: 
    p.apply_async(func, args=(i, b, c, d,)) 

Où sont les problèmes ici?

Merci!


Mise à jour: Merci aux commentaires et aux réponses, maintenant je comprends pourquoi mon exemple simple ne fonctionnera pas. Cependant, je suis toujours en difficulté avec mon vrai code. J'ai vérifié que mon func ne repose sur aucune variable globale, donc il ne semble pas être le même problème que mon exemple de code.

Comme suggéré, j'ai ajouté une valeur de retour à mon func, maintenant mon code est:

f = Flux("reactor") 
d = Detector("Ge") 
mv = arange(-6, 1.5, 0.5) 
p = Pool() 
lt = ["uee", "dee"] 
for i in lt: 
    re = p.apply_async(res, args=(i, d, f, mv,)) 
    print(re.get()) 
p.close() 
p.join() 

Maintenant, j'obtiens l'erreur suivante:

Traceback (most recent call last): 
    File "/Users/Shu/Documents/Programming/Python/Research/debug.py", line 35, in <module> 
print(re.get()) 
    File "/usr/local/Cellar/python3/3.6.0/Frameworks/Python.framework/Versions/3.6/lib/python3.6/multiprocessing/pool.py", line 608, in get 
raise self._value 
    File "/usr/local/Cellar/python3/3.6.0/Frameworks/Python.framework/Versions/3.6/lib/python3.6/multiprocessing/pool.py", line 385, in _handle_tasks 
put(task) 
    File "/usr/local/Cellar/python3/3.6.0/Frameworks/Python.framework/Versions/3.6/lib/python3.6/multiprocessing/connection.py", line 206, in send 
self._send_bytes(_ForkingPickler.dumps(obj)) 
    File "/usr/local/Cellar/python3/3.6.0/Frameworks/Python.framework/Versions/3.6/lib/python3.6/multiprocessing/reduction.py", line 51, in dumps 
cls(buf, protocol).dump(obj) 
AttributeError: Can't pickle local object 'Flux.__init__.<locals>.<lambda>' 
+0

est 'func()' ne pas créer les fichiers comme prévu, ou êtes-vous tout simplement pas voir les avantages de la vitesse? –

+0

@JohnGordon 'func' ne fait rien, comme dans mon premier exemple' cube' n'est pas exécuté. –

+0

Vous supposez que chaque processus partage le même 't' global, qui est par définition incorrenct. Vous devrez passer 't' en paramètre afin que' t' existe et soit partagé par tous les processus. –

Répondre

0

EDIT: le premier exemple que vous avez fourni ne fonctionnera pas pour une raison simple: les processus ne partagent pas la mémoire. Par conséquent, la modification t[x] = x**3 ne sera pas appliquée au processus parent, laissant les valeurs de la liste t inchangées.

Vous devez retourner la valeur du calcul et en créer une nouvelle liste.

def cube(x): 
    return x**3 

t = [0, 1, 2, 3, 4, 5] 

p = Pool() 
t = p.map(cube, t) 

print(t) 

Si, comme vous le prétendez dans le second exemple, les résultats sont censés ne pas être retourné, mais pour être stocké de façon indépendante dans les fichiers et cela ne se produit pas, je vous recommande de vérifier la valeur de retour de votre fonction pour voir si la fonction elle-même déclenche une exception ou non.

Je vous recommande d'obtenir les résultats réels et voir ce qui se passe:

p = Pool() 
for i in lt: 
    res = p.apply_async(func, args=(i, b, c, d,)) 
    print(res.get()) # this will raise an exception if it happens within func 

p.close() # do not accept any more tasks 
p.join() # wait for the completion of all scheduled jobs 
+0

Cela ne fonctionne pas pour moi .. –

+0

Édité la réponse. – noxdafox

+0

Merci pour votre patience! Maintenant, j'ai une erreur, s'il vous plaît voir ma question mise à jour. –

-1

Fonction quitte trop tôt, essayez d'ajouter au la fin de votre script ce code:

import time 
time.sleep(3)