Выполнение той же функции параллельно внутри цикла for - PullRequest
0 голосов
/ 07 апреля 2020

Используя Python 2.7, я создал образец словаря и несколько функций для подстановки этого словаря и итерации по подмножествам ...

from itertools import islice
from multiprocessing import Process
from collections import OrderedDict

global pair_dict

pair_dict = {
    1: 'one',
    2: 'two',
    3: 'three',
    4: 'four',
    5: 'five',
    6: 'six',
    7: 'seven',
    8: 'eight'
}


global test_printer



def test_printer(start_chunk, end_chunk):

    fin_dict = OrderedDict(sorted(pair_dict.items()))
    sub_dict = dict(fin_dict.items()[start_chunk:end_chunk])

    for key, value in sub_dict.iteritems():

        print key, value

    print '-' * 50



def set_chunk_start_end_points():


    # Takes the dictionary and chunks for parallel execution.

    for i in range(2, 9, 2):

        start_chunk = i - 2
        end_chunk = i

        test_printer(start_chunk, end_chunk)

        #first = Process(target=test_printer, args=(start_chunk, end_chunk)).start()

set_chunk_start_end_points()

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

Если вы закомментируете строку test_printer(start_chunk, end_chunk) и раскомментируете нижнюю строку, я ожидаю увидеть тот же вывод, просто Python использовал несколько потоков сделать это. Однако сейчас ничего не происходит.

Что я делаю не так?

Спасибо

1 Ответ

0 голосов
/ 07 апреля 2020

Я всегда считаю, что pool.map - это самый простой способ параллельно выполнять одну и ту же функцию. Может быть, вы найдете это полезным.

from itertools import islice
from multiprocessing import Pool as ProcessPool # easier to work with for this sort of thing
from collections import OrderedDict

# You were using globals wrong. But that's a separate topic.

pair_dict = {
    1: 'one',
    2: 'two',
    3: 'three',
    4: 'four',
    5: 'five',
    6: 'six',
    7: 'seven',
    8: 'eight'
}

# This only needs to be executed once. Not every time the function is called.
fin_dict = OrderedDict(sorted(pair_dict.items()))


def test_printer(chunk): # Going to make this take 1 argument. Just easier.
    start_chunk = chunk[0]
    end_chunk = chunk[1]  # All things considered this should be called chunk_end, not end_chunk

    # list for python3 compatibility
    sub_dict = dict(list(fin_dict.items())[start_chunk:end_chunk])


    # .items() for python3 compatibility
    for key, value in sub_dict.items():
        print(key, value) # Looks like you're still using Python2.7? Upgrade friend. Little support for that stuff anymore.

    print('-' * 50)



def set_chunk_start_end_points():
    # Takes the dictionary and chunks for parallel execution.
    # comment: Does it? This function takes no arguments from what I can see.
    # Think through your comments carefully.

    # Let's calculate the chunks upfront:
    chunks = [(i-2, i) for i in range(2,9,2)]

    with ProcessPool(4) as pool: # however many processes you want
        pool.map(test_printer, chunks)

set_chunk_start_end_points()

Обратите внимание, если вы не хотите указывать c чанков, pool.map будет чанк для вас. В данном случае, это фактически разделение нашего списка фрагментов!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...