Многопроцессорная обработка в Python - Попытка сжать изображение с исключением в потоке - PullRequest
0 голосов
/ 09 апреля 2020

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

import time
import os
import concurrent.futures
from multiprocessing import Pool, Process
from PIL import Image, ImageFilter

img_path = 'C:\\Users\\user\\Pics'
save_img_path = 'C:\\Users\\'
os.chdir(img_path)
img_names = [x for x in os.listdir()]
t1 = time.perf_counter()
size = (300, 300)

def process_image(img_name):

    img = Image.open(img_name)

    img = img.filter(ImageFilter.GaussianBlur(15))

    img.thumbnail(size)
    os.chdir(save_img_path)

    img.save(f'processed/{img_name}')
    print(f'{img_name} is processed...')

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

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

Вывод / Исключение:

Exception in thread Thread-1:
Traceback (most recent call last):
  File "C:\Users\user\AppData\Local\Programs\Python\Python36-32\lib\threading.py", line 916, in _bootstrap_inner
    self.run()
  File "C:\Users\user\AppData\Local\Programs\Python\Python36-32\lib\threading.py", line 864, in run
    self._target(*self._args, **self._kwargs)
  File "C:\Users\user\AppData\Local\Programs\Python\Python36-32\lib\concurrent\futures\process.py", line 295, in _queue_management_worker
    shutdown_worker()
  File "C:\Users\user\AppData\Local\Programs\Python\Python36-32\lib\concurrent\futures\process.py", line 253, in shutdown_worker
    call_queue.put_nowait(None)
  File "C:\Users\user\AppData\Local\Programs\Python\Python36-32\lib\multiprocessing\queues.py", line 129, in put_nowait
    return self.put(obj, False)
  File "C:\Users\user\AppData\Local\Programs\Python\Python36-32\lib\multiprocessing\queues.py", line 83, in put
    raise Full
queue.Full

Finished in 0.8364744000000001 seconds

1 Ответ

0 голосов
/ 21 апреля 2020

При использовании multiprocessing или concurrent.futures в ms- windows, вы должны всегда помещать фактический код выполнения в такой блок:

import time
import os
import concurrent.futures
from PIL import Image, ImageFilter


def process_image(img_name):
    img = Image.open(img_name)
    img = img.filter(ImageFilter.GaussianBlur(15))
    img.thumbnail(size)
    os.chdir(save_img_path)
    img.save(f'processed/{img_name}')
    print(f'{img_name} is processed...')


if __name__ == '__main__':
    img_path = 'C:\\Users\\user\\Pics'
    save_img_path = 'C:\\Users\\'
    os.chdir(img_path)
    img_names = [x for x in os.listdir()]
    size = (300, 300)
    t1 = time.perf_counter()
    with concurrent.futures.ProcessPoolExecutor() as executor:
        executor.map(process_image, img_names)
    t2 = time.perf_counter()
    print(f'Finished in {t2-t1} seconds')

Это необходимо из-за ограничений операционной системы.

...