LoginSignup
1
1

More than 1 year has passed since last update.

ジェネレーターでmultiprocessingに送るデータを順次用意する

Posted at

時間のかかるバッチ処理はマルチプロセスで短縮すべきです。でも、マルチプロセスってなんかわかりづらいです。

imageprocessing.py
import glob
import os.path
import cv2

dir = r'c:\data\image\'
fl = glob.glob(os.path.join(dir,'**/*'),recursive = True)
for i in fl:
    im = cv2.imread(i)
    im = imageprocess(im)
    cv2.imwrite(i, im)

こういう処理があったとして、マルチプロセスにするにはどうすればよいでしょうか。

imageprocessingmp1.py
import glob
import os.path
import cv2
from multiprocessing import Pool

def func(file):
    im = cv2.imread(file)
    im = imageprocess(im)
    cv2.imwrite(file, im)

dir = r'c:\data\image\'
fl = glob.glob(os.path.join(dir,'**/*'),recursive = True)

with Pool(4) as p:
    for _ in p.imap_unordered(func,fl):
        pass

こうなりますね。
ですが、これには少し問題があるかもしれません。
と、言うのも、これは計算結果をそのままディスクに書き出しているのですが、この部分はマルチプロセス部分なので、同時に複数の読み込みと書き出しが起きています。これはあまりよろしくはありません。出来ればそういう所はワーカープロセスでなく制御する部分に置きたいです。

imageprocessingmp2.py
import glob
import os.path
import cv2
from multiprocessing import Pool

def func(args):
    return args[0],imageprocess(args[1])

dir = r'c:\data\image\'
fl = glob.glob(os.path.join(dir,'**/*'),recursive = True)

with Pool(4) as p:
    for result in p.imap_unordered(func,[i,cv2.imread(i) for i in fl]):
         cv2.imwrite(result[0], result[1])

でもこれではダメです。最初に全部のデータをディスクから読み込むので、メモリがアホみたいに必要になります。
どうすればいいでしょう

Queueで制御する?、そう考えましたがはっきり言って面倒です。

imageprocessingmp3.py
import glob
import os.path
import cv2
from multiprocessing import Pool

def func(args):
    return args[0],imageprocess(args[1])

def files(fl):
    for i in fl:
         im = cv2.imread(i)
         yield [i,im]

dir = r'c:\data\image\'
fl = glob.glob(os.path.join(dir,'**/*'),recursive = True)

with Pool(4) as p:
    for result in p.imap_unordered(func,files(fl)):
         cv2.imwrite(result[0], result[1])

そこで、ジェネレータを使用すると、必要な時に読み込むようになります。
(送るデータが少ない場合は有る程度まとめて実行されるようです)

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1