2016-10-11 2 views
0

Предположим, у меня есть несколько генераторов (которые должны работать параллельно). Можно ли использовать многопроцессорный модуль для вызова next() на этих генераторах, чтобы обработка выполнялась параллельно?Обработка нескольких генераторов параллельно

Я хочу избежать составления списка из генераторов, так как он, скорее всего, потребляет много памяти.

Контекст: Первоначально у меня есть генератор, который выводит все связующие деревья заданного графа. Часть алгоритма включает итерацию через множество степеней подмножества соседей данной вершины. Я хотел бы распараллелить эту часть, по крайней мере, для первоначального вызова. Для определенного графика требуется около полутора секунд для вывода дерева для первых 1024 деревьев.

+0

Насколько я знаю, что это возможно. Ты это пробовал? У вас есть конкретная проблема в попытке заставить его работать? –

+0

Непонятно, что вы хотите сделать, и похоже, что многопроцессорность может оказаться неправильным решением. Почему вы не показываете короткий пример того, что вы пытаетесь сделать? – zvone

+1

@ B. Признаки моей проблемы с параллельным запуском этого процесса заключались в том, что Process/Pool отказывается иметь переданный ему объект генератора из-за отсутствия генераторов. Но, увидев текущий ответ, я понял, что могу просто передать параметры генератора и позволить дочернему процессу помещать результаты в очередь. – silverhawke

ответ

1

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

Простой пример:

import multiprocessing 
from queue import Empty 

def call_generator(generator, queue): 
    for item in generator: 
     queue.put(item) 

def process_responses(queue): 
    items = [] 
    while True: 
     try: 
      # After a one second timeout, we'll assume the generators are done 
      item = queue.get(timeout=1) 
     except Empty: 
      print('done') 
      break 

     print('item: {}'.format(item)) 

generators = [ 
    iter(range(10)), 
    iter(range(11, 20)), 
    iter(range(20, 50)) 
] 

queue = multiprocessing.Queue() 

p = multiprocessing.Process(target=process_responses, args=(queue,)) 
p.start() 


for generator in generators: 
    generator_process = multiprocessing.Process(
     target=call_generator, 
     args=(generator, queue) 
    ) 
    generator_process.start() 

p.join() # Wait for process_response to return 
+0

Не обрабатывал бы объекты-генераторы отходов в качестве аргументов из-за того, что генераторы не были сорваны? Я не думал об использовании очередей, но чтобы привести результаты; Я новичок в модуле многопроцессорности и вместо этого играл с пулами. – silverhawke

+0

(не знал, что вводить ключ автоматически добавляет комментарий) Я думаю, что это можно решить, передав параметры генератору дочернему процессу? – silverhawke

+0

Ну, я проверил этот код, и он действительно сработал. Но конечно, вы могли бы определенно структурировать его с другой целью для каждого процесса. Бассейны были бы в порядке. Однако, даже если вы используете пулы, вам все равно нужно как-то вернуть данные от генераторов к родительскому процессу - и это, вероятно, должно произойти в очереди, в трубке, в общей памяти и т. Д. – csinchok

Смежные вопросы