Асинхронная генерация перестановок с использованием пула рабочих и генератора объектов Python - PullRequest
0 голосов
/ 26 июня 2018

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

Требуемый результат:

Файл, содержащий список строк в следующем формате: PRE + СОВМЕСТНОЕ ПЕРМУТАЦИЯ

где PRE из списка 'префикс'

, где JOINEDPERMUTATION находится из "" .join (x)

где х находится из перестановок (предметов, повторений)

ПУНКТЫ - это мой список значений, которые мне нужны для получения перестановок

ПОВТОРЫ Я хочу найти каждую перестановку этого списка в диапазоне (8) повторений

items=['a','b','c']
prefix=['one','two','three']
from itertools import permutations
from multiprocessing import Pool
pool=Pool(14)

def permutations(pre, repetitions, items):
    PERMS = [ pre + "".join(x) for x in permutations(items, repetitions) ]
    return PERMS

def result_collection(result):
    results.extend(result)
    return results

results=[]

args = ((pre, repetitions, items) for pre in prefix for repetitions in range(5))

for pre, repetitions, items in args:
    pool.apply_async(permutations, (pre, repetitions, items), callback=result_collection)
pool.close()
pool.join()

with open('file.txt','a',encoding='utf-8') as file:
    file.writelines(results)

Я не получаю ошибку как таковую, но после запуска этой программы со списком, в котором в ITEMS было 50 элементов, а в PREFIXES - 5; он не был закончен через 8 часов, и я не представляю, как продолжить расследование.

Быстрый запрос, а также Прав ли я, считая, что в принципе нет смысла использовать 'pool.map' в многопроцессорном модуле, учитывая, что он когда-либо будет использовать только одного работника? Почему это здесь?

1 Ответ

0 голосов
/ 26 июня 2018

Трудно поверить, что вы не получаете ошибку как таковую, эта вещь должна вызвать RuntimeError как сумасшедший.

Внутри вновь созданного процесса загружается модуль, из которого он создается, т.е. выполняется. Это означает, что ваш код пытается создать 14 процессов, каждый из которых пытается создать 14 процессов, каждый из которых пытается создать 14 ... вы можете увидеть здесь развивающийся шаблон:)

Вы должны поместить все, что может быть выполнено только из основного процесса, в блок __name__ == '__main__'. Это предотвратит выполнение этих частей кода на рабочих, потому что для них __name__ равно __mp_name__.

Это исправит многопроцессорную часть, но есть еще одна проблема. Вы импортируете permutations из itertools, затем создаете функцию с тем же именем в своем пространстве имен, эффективно перезаписывая функцию из itertools. Когда ваши процессы вызывают вашу функцию permutations, строка PERMS = [ pre + "".join(x) for x in permutations(items, repetitions) ] вызовет TypeError, потому что вы вызываете вашу функцию перестановок там, но с двумя аргументами вместо трех, которые ваш требуется определение функции.

Это должно делать то, что вы хотите:

from itertools import permutations as it_perms
from multiprocessing import Pool
items=['a','b','c']
prefix=['one','two','three']


def permutations(pre, repetitions, items):
    PERMS = [ pre + "".join(x) for x in it_perms(items, repetitions) ]
    return PERMS

def result_collection(result):
    results.extend(result)
    return results


if __name__ == '__main__':
    pool = Pool(14)
    results = []

    args = ((pre, repetitions, items) for pre in prefix for repetitions in range(5))

    for pre, repetitions, items in args:
        pool.apply_async(permutations, (pre, repetitions, items), callback=result_collection)
    pool.close()
    pool.join()

    with open('file.txt','a',encoding='utf-8') as file:
        file.writelines(results)

Что касается вашего побочного запроса: откуда вы взяли, что pool.map () будет когда-либо использовать только одного работника? Вы можете проверить ответы на этот вопрос , особенно этот

...