#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)