Показать статус многопроцессорного скрипта без tqdm - PullRequest
0 голосов
/ 17 апреля 2020

Я пишу свой первый многопроцессорный скрипт, который впоследствии должен быть преобразован в исполняемый файл. Я хотел бы иметь обзор, сколько файлов списка уже обработано. Но если я использую tqdm для этого, мой исполняемый файл становится очень большим. Поэтому я ищу решение, чтобы получить впечатление, как долго задача еще работает. Не имеет значения, является ли это индикатором выполнения или просто выводом в консоли, например «10 из 120 файлов готово». У кого-нибудь есть подсказка, как это сделать? Я должен передать несколько аргументов a, b, c, d, e многопроцессорному инструменту, поэтому мне нужно дополнительно использовать «частичное». Затем я получаю одно возвращаемое значение для каждого обработанного файла. Вот мой код, как он работает без отображения статуса выполнения:

import multiprocessing
from functools import partial

pool = multiprocessing.Pool(multiprocessing.cpu_count())
prod_x=partial(doSomething, a=a, b=b, c=c, d=0, e=e)
totalResult= list((pool.imap_unordered(prod_x, listOfFiles)))

Функция doSomething вычисляет что-то, и это делается для каждого файла. Параметр totalResult представляет собой список всех возвращаемых значений

1 Ответ

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

Самый простой способ справиться с этим, вероятно, использовать pool.apply_async для отправки ваших работ. Затем вам нужно определить обратный вызов, который будет выполняться каждый раз, когда задание выполнено.

Если вы хотите проинформировать пользователя о том, сколько заданий уже выполнено, обратному вызову требуется некоторая «память» о количестве выполненных заданий. Это может быть либо глобальная переменная, либо класс, который я считаю более предпочтительным.

Комбинируя эти точки, решение может выглядеть примерно так:

import multiprocessing
import time


class ProgressUpdater:
    def __init__(self, num_items):
        self.num_items = num_items
        self.num_processed = 0

    def update(self, data):
        self.num_processed += 1
        print(f"Done processing {self.num_processed} of {self.num_items} inputs")


def func(item):
    time.sleep(item // 10)
    return item // 2


if __name__ == "__main__":
    item_list = [3, 5, 7, 32, 6, 21, 12, 1, 7]
    progress_updater = ProgressUpdater(len(item_list))

    with multiprocessing.Pool(3) as pool:
        result_objects = [
            pool.apply_async(func, (item,), callback=progress_updater.update)
            for item in item_list
        ]
        results = [result_object.get() for result_object in result_objects]
    pool.join()

    print(results)

Теперь, чтобы удовлетворить ваши потребности, вы нужно слегка помассировать, используя ваши partial функции et c.

...