Je m'interroge sur la façon dont la classe Multiprocessing.Pool de python fonctionne avec map, imap et map_async. Mon problème particulier est que je veux map sur un itérateur qui crée des objets lourds en mémoire, et que je ne veux pas que tous ces objets soient générés en mémoire en même temps. Je voulais voir si les différentes fonctions map() allaient tordre mon itérateur à sec, ou appeler intelligemment la fonction next() uniquement lorsque les processus enfants avancent lentement, j'ai donc bricolé quelques tests en ce sens :
def g():
for el in xrange(100):
print el
yield el
def f(x):
time.sleep(1)
return x*x
if __name__ == '__main__':
pool = Pool(processes=4) # start 4 worker processes
go = g()
g2 = pool.imap(f, go)
g2.next()
Et ainsi de suite avec map, imap, et map_async. Il s'agit cependant de l'exemple le plus flagrant, car le simple fait d'appeler next() une seule fois sur g2 imprime tous les éléments de mon générateur g(), alors que si imap faisait cela "paresseusement", je m'attendrais à ce qu'il n'appelle go.next() qu'une seule fois, et n'imprime donc que "1".
Quelqu'un peut-il clarifier ce qui se passe, et s'il existe un moyen de faire en sorte que le pool de processus évalue "paresseusement" l'itérateur selon les besoins ?
Merci,
Gabe
0 votes
Après avoir retiré le
time.sleep
et l'ajout d'unprint os.getpid(), x
surf
le comportement est encore plus bizarre, parfois seulement 2 ou 3 PID différents sont imprimés et font toujours un nombre différent d'itérations... BTW quelle version de Python utilisez-vous ?0 votes
Python 2.6.6 (r266:84292, Dec 26 2010, 22:31:48) Installation standard debian.