#python #multiprocessing #iteration
#python #многопроцессорная обработка #итерация
Вопрос:
Я хочу вызвать свою функцию n раз с многопроцессорной обработкой (чтобы сэкономить время) и сохранить результаты в массиве numpy:
num=N # number of trials
results=np.zeros([N,2]) # array of results (2 because function produces 2 results)
def f(): #function with no arguments because the process is based on randomness
....
return a, b #results are float64 type
Я хочу что-то вроде этого:
for i in range(num):
results[i]=f()
но с использованием многопроцессорной обработки. Есть ли способ?
Я пробовал это, но не сработало:
from multiprocessing import Pool
if __name__ == '__main__':
with Pool(15) as p:
for i in range(num):
result[i]=(p.map(f,iterable=i))
Ответ №1:
Вы можете добиться этого, вызвав apply_async()
метод, который принадлежит Pool
классу, и сохранив AsyncResult
объекты в списке. Вам также нужно не забывать вызывать close()
join()
методы и . После завершения всех процессов вы можете собирать результаты из AsyncResult
объектов. В следующем примере f()
функция будет выполняться всего 100 раз, но одновременно будет запущено не более 4 процессов (не считая процесса, который запускает другие). Я уверен, что код можно оптимизировать еще больше, но это может быть хорошей отправной точкой.
import multiprocessing as mp
import numpy as np
def f():
# you perform your calculations here
result = 0, 0 # this is only for testing
return result
if __name__ == '__main__':
count = 100
async_results = []
with mp.Pool(processes=4) as pool:
for _ in range(count):
async_results.append(pool.apply_async(f))
pool.close()
pool.join()
results = np.zeros([count, 2])
for i, async_result in enumerate(async_results):
results[i] = async_result.get()
print(results)
Комментарии:
1. Спасибо! Это работает, но у меня все еще есть проблема, и это довольно странно: если я ставлю count = 10, например, это работает отлично, но если я ставлю count = 100, процессор и память работают на максимальной мощности (так что это хорошо), но после этого, когда они заканчивают, код никогда не останавливается, и spyder зависает, выдаваяу меня нет результатов, и это невозможно остановить! Я должен отключить ее с помощью диспетчера задач. Есть идеи??
2. Я думаю, мне нужен способ ограничить количество процессов. В моем первом посте, где я пытался использовать mp. Пул, я установил 15 в качестве ограничения для процессора (или так я понимаю из документации), но здесь я не вижу ничего, что устанавливает ограничение. Я прав? Есть ли какое-либо решение?
3. Если вы установите значение count равным 100, он запустит 100 процессов одновременно, и они будут работать одновременно.
4. хорошо, но, как я вижу в коде, который вы предлагаете, вы вводите count=15 и получаете результат в виде массива с тем же размером строки ([count,2] ), поэтому я понял, что count означает испытания. Для моего кода мне нужно выполнить 100 000 проб, так как я могу изменить код для достижения этой цели? Заранее благодарю!!
5. У меня может быть идея. Я отредактирую ответ через мгновение.