Зависание программы на Python при чередовании многопроцессорной и одиночной обработки

#python #multiprocessing #multiprocess

#python #многопроцессорная обработка #многопроцессорность

Вопрос:

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

Программа просто загружает кучу изображений, выполняет над ними несколько операций и сохраняет их.
Я делаю то же самое, первый раз обычно, а второй раз с использованием многопроцессорной обработки:

 import cv2
import time
import os
import concurrent.futures


def main():

    path = "orig_images/"
    img_paths_list = [f"{path}{img_name}" for img_name in os.listdir(path)]

    ## single processing
    print("Single processing")
    time_start = time.time()
    for img_path in img_paths_list:
        result = process_image(img_path)
        print(result)
    time_end = time.time()
    print(f"Finished in {round(time_end - time_start, 2)} s")


    ## multiprocessing
    print("Multiprocessing")
    time_start = time.time()
    results = []
    with concurrent.futures.ProcessPoolExecutor() as executor:
        results = [executor.submit(process_image, img_path) for img_path in img_paths_list]

    for f in concurrent.futures.as_completed(results):
        print(f.result())
    time_end = time.time()
    print(f"Finished in {round(time_end - time_start, 2)} s")


def process_image(img_path):
    img = cv2.imread(img_path)
    img = cv2.GaussianBlur(img, (5,5), 0)
    img = cv2.resize(img, dsize=(1200,1200))
    img_name = os.path.split(img_path)[1]
    cv2.imwrite(f"mod_images/{img_name}", img)
    result = f"Image {img_name} was processed"
    return(result)



if __name__ == "__main__":
    main()


  

Теперь у меня возникает странная проблема … задача выполняется с первого раза (однократная обработка), но затем она застревает в начале части многопроцессорной обработки, то есть на

 print("Multiprocessing")
  

инструкция. Если я переключу две части, т. Е. я выполняю задачу с помощью многопроцессорной обработки, а затем нормально, она завершается без каких-либо проблем.

Я не понимаю, что я здесь делаю неправильно.

Комментарии:

1. Я попробовал ваш код, и он работает без каких-либо проблем

2. Я не уверен, почему вы зависаете; это может быть что-то специфичное для того, что process_image делает. Но я могу сказать вам, что, имея ваш as_completed цикл после with ... as executor: блока, он не будет выполняться до тех пор, пока не будут завершены все отправленные задачи, и, следовательно, нарушает свою цель. То есть ее следует переместить в with блок, чтобы вы действительно получали результаты по мере выполнения задач. Это не повлияет на общее время, поскольку вам интересно знать, когда завершатся все задачи, но я просто сообщаю вам, что вы непоследовательны (… подробнее)

3. С таким же успехом вы могли бы просто не использовать as_completed and вместо for f in results: print(f.result()) . Кроме того, results неправильно назван, поскольку на самом деле это не результаты, а список Future экземпляров. Лучшее название futures .

4. Или вы можете сделать: results = executor.map(process_image, img_paths_list) за которым следует for result in results: print(result)