Я согласен, что использование Pool
из multiprocessing
, вероятно, является наилучшим маршрутом, если вы хотите остаться в стандартной библиотеке. Если вы заинтересованы в выполнении других типов параллельной обработки, но не изучаете ничего нового (т.е. все еще используете тот же интерфейс, что и multiprocessing
), то вы можете попробовать pathos
, который предоставляет несколько форм параллельных карт и имеет в значительной степени тот же интерфейс, что и multiprocessing
.
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)]
Кроме того, pathos
имеет дочерний пакет с тем же интерфейсом, который называется pyina
, который запускает mpi4py
, но предоставляет ему параллельные карты, которые работают в MPI и могут запускаться с использованием нескольких планировщиков.
Еще одно преимущество заключается в том, что pathos
поставляется с гораздо лучшим сериализатором, чем вы можете получить в стандартном Python, поэтому он гораздо более эффективен, чем multiprocessing
, для сериализации ряда функций и других вещей. И вы можете сделать все от переводчика.
>>> 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]
>>>
Получить код здесь: https://github.com/uqfoundation