Задача, которую я пытаюсь решить, - обработать тысячи артефактов разного размера на многоядерной машине. Я использую 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()
Запуск демо
Конечно, вместо чисел я буду отображать имена файлов.
Теперь вопросы:
- Есть ли лучший pythoni c способ достичь того, чего я хочу?
- Последний пункт об очистке pbar кажется мне неприятным. Я делаю это в основном для того, чтобы очистить терминал после завершения программы. Может, есть способ получше?