Tqdm для индикатора выполнения для каждого рабочего пула процессов - PullRequest
0 голосов
/ 12 июля 2020

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

Пока что у меня есть следующее:

from concurrent.futures import ProcessPoolExecutor

from itertools import islice, cycle

import time
import tqdm
import multiprocessing
import random

worker_count = min(multiprocessing.cpu_count(), 10)
flist=range(100)
executor = ProcessPoolExecutor(max_workers=worker_count)

with tqdm.tqdm(total=len(flist), leave=False) as t:
    t.set_description_str("Extracting ... ")
    pbars = []

    for idx in range(t.pos + 1, t.pos + 1 + worker_count):
        pbars.append(tqdm.tqdm(position=idx, bar_format='{desc}', leave=False))

    def process(entry):
        artifact, idx = entry
        time.sleep(random.randint(0, worker_count)/10.0)
        pbars[idx].set_description_str(f'Working on {artifact}', refresh=True)
        return artifact
    for _, _ in zip(flist, executor.map(process, zip(flist, islice(cycle(range(worker_count)), len(flist))))):
        t.update()

    for idx in range(worker_count):
        pbars[idx].set_description_str(" "*(pbars[idx].ncols - 1), refresh=True)
        pbars[idx].clear()
        pbars[idx].close()

Запуск демо

Конечно, вместо чисел я буду отображать имена файлов.

Теперь вопросы:

  1. Есть ли лучший pythoni c способ достичь того, чего я хочу?
  2. Последний пункт об очистке pbar кажется мне неприятным. Я делаю это в основном для того, чтобы очистить терминал после завершения программы. Может, есть способ получше?
...