многопроцессорная обработка [concurrent.futures.ProcessPoolExecutor] неправильно вызывает функцию - PullRequest
0 голосов
/ 03 апреля 2020

Здравствуйте, коллеги-программисты, я новичок в многопроцессорности. Я смотрел это руководство по многопроцессорности: https://www.youtube.com/watch?v=fKl2JW_qrso&t=2367s и пытаюсь заставить код работать. По сути, это означает чтение нескольких изображений и сохранение их в папке processed.

ссылка на zip (130 МБ): https://ufile.io/kt420x7q

Весь код:

import time
import concurrent.futures
from pathlib import Path
from PIL import Image, ImageFilter

parent_path = Path(__file__).parent
output_path = parent_path.joinpath('processed')

def process_image(img_name):
    img = Image.open(img_name)
    img = img.filter(ImageFilter.GaussianBlur(15))
    img.thumbnail(size)
    img.save(f'{output_path.joinpath(img_name)}')
    print(f'{img_name} was processed...')

def main():
    img_names = [
        'photo-1532009324734-20a7a5813719.jpg',
        'photo-1524429656589-6633a470097c.jpg',
        'photo-1530224264768-7ff8c1789d79.jpg',
        'photo-1541698444083-023c97d3f4b6.jpg',
        'photo-1522364723953-452d3431c267.jpg',
        'photo-1513938709626-033611b8cc03.jpg',
        'photo-1493976040374-85c8e12f0c0e.jpg',
        'photo-1504198453319-5ce911bafcde.jpg',
        'photo-1530122037265-a5f1f91d3b99.jpg',
        'photo-1516972810927-80185027ca84.jpg',
        'photo-1550439062-609e1531270e.jpg']

    t1 = time.perf_counter()
    size = (1200, 1200)

##     # Normal Loop Function
##    for img_name in img_names:
##        img = Image.open(img_name)
##        img = img.filter(ImageFilter.GaussianBlur(15))
##        img.thumbnail(size)
##        img.save(f'{output_path.joinpath(img_name)}')
##        print(f'{img_name} was processed...')

    # Multiprocessing Function
    with concurrent.futures.ProcessPoolExecutor() as executor:
        executor.map(process_image, img_names)

    t2 = time.perf_counter()
    print(f'Finished in {t2-t1} seconds')

if __name__ == '__main__':
    main()

##input()

Как видите, есть Normal Loop Function и Multiprocessing Function. Предполагается, что MP-function делает то же самое, что и Normal Loop Function, но, похоже, не выполняет process_image функцию должным образом.

Когда я запускаю:

 # Normal Loop Function
for img_name in img_names:
    img = Image.open(img_name)
    img = img.filter(ImageFilter.GaussianBlur(15))
    img.thumbnail(size)
    img.save(f'{output_path.joinpath(img_name)}')
    print(f'{img_name} was processed...')

, он работает, как предполагалось, для печати прогресса и сохранения изображений в папку processed:

photo-1532009324734-20a7a5813719.jpg was processed...
photo-1524429656589-6633a470097c.jpg was processed...
photo-1530224264768-7ff8c1789d79.jpg was processed...
photo-1541698444083-023c97d3f4b6.jpg was processed...
photo-1522364723953-452d3431c267.jpg was processed...
photo-1513938709626-033611b8cc03.jpg was processed...
photo-1493976040374-85c8e12f0c0e.jpg was processed...
photo-1504198453319-5ce911bafcde.jpg was processed...
photo-1530122037265-a5f1f91d3b99.jpg was processed...
photo-1516972810927-80185027ca84.jpg was processed...
photo-1550439062-609e1531270e.jpg was processed...
Finished in 11.8887978 seconds

Но когда я пытаюсь запустите MP-Function:

# Multiprocessing Function
with concurrent.futures.ProcessPoolExecutor() as executor:
    executor.map(process_image, img_names)

с выводом:

Finished in 3.8939473 seconds

В этом случае прогресс не печатается вообще, а изображения не сохраняются в папке processed. Этот вывод получен из выполнения кода в IDLE. Поскольку у IDLE, похоже, есть проблемы с многопроцессорностью, я также попытался выполнить скрипт, запустив его из терминала windows. В этом случае нет выходных данных, и процесс продолжает работать бесконечно.

...