Je suis d'accord que l'utilisation d' Pool
de multiprocessing
est probablement le meilleur itinéraire si vous souhaitez rester à l'intérieur de la bibliothèque standard. Si vous êtes intéressé à faire d'autres types de traitement en parallèle, mais ne pas apprendre quelque chose de nouveau (c'est à dire toujours à l'aide de la même interface que multiprocessing
), alors vous pouvez essayer de l' pathos
, qui propose plusieurs formules de parallèle de cartes et de a à peu près la même interface que multiprocessing
n'.
Python 2.7.6 (default, Nov 12 2013, 13:26:39)
[GCC 4.2.1 Compatible Apple Clang 4.1 ((tags/Apple/clang-421.11.66))] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import numpy
>>> numToFactor = 976
>>> def isFactor(x):
... result = None
... div = (numToFactor / x)
... if div*x == numToFactor:
... result = (x,div)
... return result
...
>>> from pathos.multiprocessing import ProcessingPool as MPool
>>> p = MPool(4)
>>> possible = range(1,int(numpy.floor(numpy.sqrt(numToFactor)))+1)
>>> # standard blocking map
>>> result = [x for x in p.map(isFactor, possible) if x is not None]
>>> print result
[(1, 976), (2, 488), (4, 244), (8, 122), (16, 61)]
>>>
>>> # asynchronous map (there's also iterative maps too)
>>> obj = p.amap(isFactor, possible)
>>> obj
<processing.pool.MapResult object at 0x108efc450>
>>> print [x for x in obj.get() if x is not None]
[(1, 976), (2, 488), (4, 244), (8, 122), (16, 61)]
>>>
>>> # there's also parallel-python maps (blocking, iterative, and async)
>>> from pathos.pp import ParallelPythonPool as PPool
>>> q = PPool(4)
>>> result = [x for x in q.map(isFactor, possible) if x is not None]
>>> print result
[(1, 976), (2, 488), (4, 244), (8, 122), (16, 61)]
Aussi, pathos
a une sœur paquet avec la même interface, appelée pyina
, qui s'exécute mpi4py
, mais fournit en parallèle des cartes qui s'exécutent en MPI et peut être exécuté à l'aide de plusieurs planificateurs.
Un autre avantage est qu' pathos
est livré avec une bien meilleure sérialiseur que vous pouvez obtenir en standard de python, il est donc beaucoup plus capables que d' multiprocessing
lors de la sérialisation d'un éventail de fonctions et d'autres choses. Et vous pouvez tout faire à partir de l'interprète.
>>> class Foo(object):
... b = 1
... def factory(self, a):
... def _square(x):
... return a*x**2 + self.b
... return _square
...
>>> f = Foo()
>>> f.b = 100
>>> g = f.factory(-1)
>>> p.map(g, range(10))
[100, 99, 96, 91, 84, 75, 64, 51, 36, 19]
>>>
Obtenir le code ici: https://github.com/uqfoundation