Вывод прогресс-бара в Python с multiprocessing и tqdm

Пройдите тест, узнайте какой профессии подходите

Я предпочитаю
0%
Работать самостоятельно и не зависеть от других
Работать в команде и рассчитывать на помощь коллег
Организовывать и контролировать процесс работы

Быстрый ответ

Погрузимся в параллельное выполнение задач! Примените tqdm в многопроцессорных приложениях с использованием общих ресурсов для визуализации прогресса. Вот как это выглядит:

Python
Скопировать код
from multiprocessing import Process, Manager, Lock
from tqdm import tqdm

def worker(counter, lock):
    with lock:
        counter.value += 1

if __name__ == "__main__":
    manager = Manager()
    counter = manager.Value('i', 0)
    lock = Lock()
    workers = 10
    
    with tqdm(total=workers) as progress_bar:
        processes = [Process(target=worker, args=(counter, lock)) for _ in range(workers)]
        for process in processes:
            process.start()
        
        while any(process.is_alive() for process in processes):
            progress_bar.update(n=counter.value – progress_bar.n)

    for process in processes:
        process.join()

Данный код обновляет индикатор прогресса tqdm в реальном времени по мере увеличения значения счётчика рабочими процессами. Не обязательно использовать time.sleep() — мы же не в отпуске!

Кинга Идем в IT: пошаговый план для смены профессии

Когда следует использовать multiprocessing.Pool imap, imap_unordered?

С помощью multiprocessing, а именно Pool.imap или Pool.imap_unordered, вы сможете полностью задействовать CPU. Разберёмся, в чём их специфика.

Упорядоченный прогресс с imap

imap — это версия функции map, адаптированная для многопроцессорности, которая возвращает результаты стриктно по порядку. Её интеграция с tqdm выглядит так:

Python
Скопировать код
from multiprocessing import Pool
from tqdm import tqdm

def heavy_lifter(x):
    return x * x

if __name__ == '__main__':
    pool_size = 4
    tasks = range(1000)
    with Pool(pool_size) as pool:
        results = list(tqdm(pool.imap(heavy_lifter, tasks), total=len(tasks)))

Быстрый результат с imap_unordered

В свою очередь imap_unordered возвращает результаты по мере их выполнения, не учитывая исходный порядок.

Python
Скопировать код
results = list(tqdm(pool.imap_unordered(heavy_lifter, tasks), total=len(tasks)))

Ускорение индикатора прогресса с помощью process_map

Функция process_map из модуля tqdm.contrib.concurrent позволяет удобно отслеживать прогресс выполнения ваших задач.

Python
Скопировать код
from tqdm.contrib.concurrent import process_map

results = process_map(heavy_lifter, tasks, max_workers=pool_size, chunksize=10)

Для работы требуется версия tqdm 4.42.0 или более новая. Не забывайте об обновлениях!

Подводные камни и способы их устранения

Вот несколько ключевых моментов для успешного использования многопроцессорности:

Выбор между порядком и скоростью

Применяйте imap для последовательности, imap_unordered — для скорости.

Особенности оценки времени

С imap_unordered время выполнения может оказаться непредсказуемым.

Подходящий инструмент для задачи

Используйте различные методы класса Pool, наиболее подходящие для вашей задачи.

Корректное завершение работы

Используйте Pool в контекстном менеджере для правильного освобождения ресурсов после завершения задач.

Визуализация

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

Python
Скопировать код
from multiprocessing import Pool
from tqdm import tqdm

with Pool(processes=4) as pool:
    r = list(tqdm(pool.imap_unordered(func, tasks), total=len(tasks)))

Расширение возможностей с помощью сторонних библиотек

Не ограничивайтесь стандартной библиотекой. Используйте всё разнообразие доступных инструментов.

Знакомтесь: p_tqdm

p_tqdm удобно комбинирует многопроцессорность и визуализацию прогресса. Следите за обновлениями на GitHub!

Работа с Chunksize

Chunksize – мощный инструмент для эффективной настройки производительности вашей программы.

Непрерывное развитие

Следите за обновлениями tqdm. Даже малейшие изменения могут значительно улучшить работу.

Полезные материалы

  1. GitHub – tqdm/tqdm
  2. multiprocessing – Python 3.12.2 Documentation
  3. tqdm.tqdm – Документация tqdm
  4. Real Python – Полное руководство по многопроцессорности
  5. concurrent.futures – Python 3.12.2 Documentation
  6. Beginner's Guide to Concurrency and Parallelism in Python – Toptal®
  7. Python Multiprocessing Tutorial: Run Code in Parallel Using the Multiprocessing Module – YouTube