Цикл параллельной обработки с использованием многопроцессорного пула
Я хочу обрабатывать большой цикл for параллельно, и из того, что я прочитал, лучший способ сделать это - использовать библиотеку многопроцессорности, которая входит в стандартную комплектацию с Python.
У меня есть список из около 40 000 объектов, и я хочу обрабатывать их параллельно в отдельном классе. Причина этого в отдельном классе объясняется главным образом тем, что я читал здесь.
В одном классе у меня есть все объекты в списке и через функции multiprocessing.Pool и Pool.map. Я хочу выполнять параллельные вычисления для каждого объекта, заставляя его проходить через другой класс и возвращать значение.
# ... some class that generates the list_objects
pool = multiprocessing.Pool(4)
results = pool.map(Parallel, self.list_objects)
И тогда у меня есть класс, который я хочу обработать каждый объект, переданный функцией pool.map:
class Parallel(object):
def __init__(self, args):
self.some_variable = args[0]
self.some_other_variable = args[1]
self.yet_another_variable = args[2]
self.result = None
def __call__(self):
self.result = self.calculate(self.some_variable)
Причина, по которой у меня есть метод вызова, связана с сообщением, которое я связал ранее, но я не уверен, что правильно его использую, поскольку он, кажется, не имеет никакого эффекта. Я не получаю значение self.result.
Любые предложения?
Спасибо!
Ответы
Ответ 1
Используйте, если это возможно, обычную функцию, а не класс. Используйте класс только тогда, когда есть явное преимущество для этого.
Если вам действительно нужно использовать класс, то, учитывая вашу настройку, передайте экземпляр Parallel:
results = pool.map(Parallel(args), self.list_objects)
Так как экземпляр имеет метод __call__
, сам экземпляр может быть вызван, как функция.
Кстати, __call__
должен принять дополнительный аргумент:
def __call__(self, val):
поскольку pool.map
по существу будет вызывать параллель
p = Parallel(args)
result = []
for val in self.list_objects:
result.append(p(val))
Ответ 2
Pool.map
просто применяет функцию (фактически, вызываемую) параллельно. Он не имеет понятия об объектах или классах. Поскольку вы передаете ему класс, он просто вызывает __init__
- __call__
никогда не выполняется. Вам нужно либо явно вызвать его из __init__
, либо использовать pool.map(Parallel.__call__, preinitialized_objects)