Параллельные процессы перезаписывают индикаторы выполнения (tqdm) - PullRequest
1 голос
/ 20 июня 2019

Я пишу скрипт на Python 3.7, который запускает несколько параллельных задач, используя multiprocessing.Process (задача на ядро).Чтобы отследить прогресс для каждого процесса, я использовал библиотеку tqdm, которая реализует индикатор выполнения.Мой код выглядит следующим образом:

with tqdm(total=iterator_size) as progress_bar:
     for row in tqdm(batch):
         process_batch(batch)
         progress_bar.update(1)

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

enter image description here

По окончании консоль правильно отображает заполненные индикаторы выполнения:

enter image description here

Моя цель - обновлять индикаторы выполнения, не перезаписывая друг друга.Есть ли способ, которым я могу достичь этого?

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

Все решения онлайн адрес multiprocess.Pool, но я не планирую менять свою архитектуру, так как я могу получить максимальную отдачуmultiprocess.Process.

1 Ответ

1 голос
/ 09 июля 2019

Для обновления без перезаписи вам нужно использовать параметр position в tqdm, который вы можете найти здесь . Здесь position=0 для самой внешней панели, position=1 для следующей и т. Д., Где 0 и 1 - количество строк, которые нужно пропустить перед печатью индикатора выполнения, т. Е. 0 означает индикатор выполнения после 0 строк, а 1 означает 1 после линия. Поскольку position принимает количество пропускаемых строк, для него требуется индекс процесса, который мы можем получить с помощью multiprocessing.current_process

(ПРИМЕЧАНИЕ. Не вводите число pid, так как оно пропустит столько строк перед печатью)

from multiprocessing import current_process

""" Your code Here
Here, the current_process() is the process object
current_process().name gives the name of the process
current_process()._identity gives a tuple of the number of process
"""

current = current_process()
with tqdm(total=iterator_size) as progress_bar:
    for row in tqdm(batch, desc=str(current.name),
              position=current._identity[0] - 1)):
        process_batch(batch)
        progress_bar.update(1)
...