Создайте процесс для параллельной работы нескольких генераторов, используя multiprocess.Process без предварительного составления списка - PullRequest
0 голосов
/ 20 декабря 2018

У меня есть список крупных генераторов, таких как:

test_list = [(i for i in range(100000000)) for x in range(100)]

Это намного больше, чем у меня, но демонстрирует причину для генератора.

Я хочу оценить функцию на каждомнезависимо от генератора:

def test_function(generator):
    results = []
    for i in range(3):
        results.append(next(generator))
    return results

Для такой функции имеет смысл не преобразовывать весь генератор в список перед применением функции.

Я хочу запустить его параллельно:

import multiprocessing as mp

output = mp.Queue()

processes = [mp.Process(target=test_function, args=(generator, )) for generator in test_list]

# Run processes
for p in processes:
    p.start()

# Exit the completed processes
for p in processes:
    p.join()

# Get process results from the output queue
results = [output.get() for p in processes]

Однако я получаю сообщение об ошибке, что генератор не может быть засечен.

Как можно запуститьэтот процесс параллельно?

Спасибо, Джек

1 Ответ

0 голосов
/ 20 декабря 2018

Вместо генераторов, которые не могут быть засечены (см. Этот ответ , если вы хотите знать почему), используйте итераторы, которые можно засечь, и это просто объекты с методом __next__(), так что выможете позвонить next() на них.Например:

class first_n_squares:
    def __init__(self, n):
        self.i = 0
        self.n = n

    def __next__(self):
        if self.i < self.n:
            ret = self.i ** 2
            self.i += 1
            return ret
        else:
            raise StopIteration

Экземпляр first_n_squares является итератором, поэтому его можно засечь, и вы можете вызвать next() для него.Например:

first_5_squares_iter = first_n_squares(5)
first_square = next(first_5_squares_iter)
...