Как сделать так, чтобы мультипроцессорная функция возвращала и сохраняла значения в python? - PullRequest
0 голосов
/ 07 ноября 2019

У меня есть функция, которую я буду запускать с использованием мультиобработки. Однако функция возвращает значение, и я не знаю, как сохранить это значение, как только оно будет сделано.

Я где-то читал в Интернете об использовании очереди, но я не знаю, как ее реализовать или дажеработа.

cores = []
for i in range(os.cpu_count()):
    cores.append(Process(target=processImages, args=(dataSets[i],))) 
for core in cores: 
    core.start()
for core in cores:
    core.join()

Где функция 'processImages' возвращает значение. Как сохранить возвращенное значение?

Ответы [ 3 ]

0 голосов
/ 07 ноября 2019

Если вы хотите использовать результат object, возвращаемый мультипроцессором, попробуйте этот

from multiprocessing.pool import ThreadPool


def fun(fun_argument1, ... , fun_argumentn):
    <blabla>
    return object_1, object_2


pool = ThreadPool(processes=number_of_your_process)
async_num1 = pool.apply_async(fun, (fun_argument1, ... , fun_argumentn))
object_1, object_2 = async_num1.get()

, тогда вы можете делать все, что захотите.

0 голосов
/ 07 ноября 2019

Вы не можете вернуть переменную из другого процесса. Рекомендованным способом было бы создать Queue (multiprocessing.Queue), затем ваш подпроцесс поместил бы результаты в эту очередь, и как только это будет сделано, вы можете прочитать их обратно - это работает, если у вас много результатов.

Если вам просто нужно одно число - использование Value или Array может быть проще.

Просто помните, вы не можете использовать простую переменную для этого, ее нужно обернутьс вышеупомянутыми классами из multiprocessing lib.

0 голосов
/ 07 ноября 2019

В вашем фрагменте кода вы вводите dataSets , который является списком некоторого неопределенного размера. У вас есть функция processImages , которая принимает элемент dataSet и, по-видимому, возвращает значение, которое вы хотите захватить.

cpu_count == длина набора данных?

Первая проблема, которую я заметил, этотот os.cpu_count () управляет диапазоном значений i , который затем определяет, какие наборы данных вы обрабатываете. Я предполагаю, что вы предпочли бы, чтобы эти две вещи были независимыми. То есть вы хотите иметь возможность сократить некоторое количество наборов данных X, и вы хотите, чтобы оно работало на любой машине, имеющей от 1 до 1000 (или более ...) ядер.

Отдельно от процессораограниченная работа

Я также собираюсь предположить, что вы уже определили, что задача действительно связана с процессором, поэтому имеет смысл разделить ее по ядрам. Если вместо этого ваша задача связана с диском, вам нужно больше рабочих. Вы также можете быть привязаны к памяти или кешу. Если для вас важно оптимальное распараллеливание, вам следует подумать о том, чтобы провести несколько испытаний, чтобы определить, какое количество работников действительно дает вам максимальную производительность.

Вот еще чтение , если вам нравится

Класс пула

В любом случае, как упоминал Майкл Бучер, класс пула упрощает это для вас. Ваш стандартный вариант использования. У вас есть набор работы, которую нужно выполнить (ваш список наборов данных для обработки) и количество рабочих, которые должны это сделать (во фрагменте кода - количество ядер).

TLDR

Используйте такие простые концепции многопроцессорной обработки, как это:

 from multiprocessing import Pool

 # Renaming this variable just for clarity of the example here
 work_queue = datasets

 # This is the number you might want to find experimentally. Or just run with cpu_count()
 worker_count = os.cpu_count()

 # This will create processes (fork) and join all for you behind the scenes
 worker_pool = Pool(worker_count)

 # Farm out the work, gather the results. Does not care whether dataset count equals cpu count
 processed_work = worker_pool.map(processImages, work_queue)

 # Do something with the result
 print(processed_work)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...