Python MultiProcessing のサンプルコード

まあ、この辺 の 話なんですけど、各map系関数でどう書けばいいのか試行錯誤したのでメモ。

追記: imap_unordered の例で f を重くしてやってみたら,なんだか arg_iter あたりで暴走しているみたいに cpu を食って最後には Killed といって終了してしまう. ちょっとまだ何が起きているのかわからないが,表面のコードではなくて mp の内側で なにか起きているっぽい.

#! /usr/local/bin/python3

import multiprocessing as mp
import os
import time

def arg_iter():
  """ 各種map系関数で実行する関数(ここでのf)の引数を渡すためのジェネレータ。
      for文で回せばいつか終了するし、whileでやればこけない限り走り続けるはず。
  """
  #while True:
  for i in range(5):
    yield (1, 2, 3)

def f(a):
  """ 並列に実行されるべき関数。重い計算とか。
  """
  print(os.getppid(), '-', os.getpid())
  return (a[0]+a[1]+a[2], os.getpid())

if __name__ == '__main__':

  print('__main__', os.getpid())

  print('##### map #####')
  with mp.Pool(processes=2) as pool:
    result = pool.map(f, arg_iter())
  print('result', result)
  # map()だけはpoolのスコープの外であってもresultを参照できる。
  # その他のmap系関数ではpoolのスコープ内でなければブロックされる。

  print('##### map_async #####')
  with mp.Pool(processes=2) as pool:
    result = pool.map_async(f, arg_iter())
    print('result', result.get())

  print('##### imap #####')
  with mp.Pool(processes=2) as pool:
    result = pool.imap(f, arg_iter())
    for r in result:
      print('result', r)

  print('##### imap_unordered #####')
  with mp.Pool(processes=2) as pool:
    result = pool.imap_unordered(f, arg_iter())
    for r in result:
      print('result', r)

そして実行結果。

__main__ 18279
##### map #####
18279 - 18682
18279 - 19045
18279 - 18682
18279 - 19045
18279 - 18682
result [(6, 18682), (6, 19045), (6, 18682), (6, 19045), (6, 18682)]
##### map_async #####
18279 - 19476
18279 - 19851
18279 - 19476
18279 - 19851
18279 - 19476
result [(6, 19476), (6, 19851), (6, 19476), (6, 19851), (6, 19476)]
##### imap #####
18279 - 19880
18279 - 20284
18279 - 19880
18279 - 20284
18279 - 19880
result (6, 19880)
result (6, 20284)
result (6, 19880)
result (6, 20284)
result (6, 19880)
##### imap_unordered #####
18279 - 20543
18279 - 20730
18279 - 20543
18279 - 20730
18279 - 20543
result (6, 20543)
result (6, 20730)
result (6, 20543)
result (6, 20730)
result (6, 20543)

2019/Sep 頃書いた。