8

次のコードがあります。

def main():
  (minI, maxI, iStep, minJ, maxJ, jStep, a, b, numProcessors) = sys.argv
  for i in range(minI, maxI, iStep):
    for j in range(minJ, maxJ, jStep): 
      p = multiprocessing.Process(target=functionA, args=(minI, minJ))
      p.start()
      def functionB((a, b)):
        subprocess.call('program1 %s %s %s %s %s %s' %(c, a, b, 'file1', 
          'file2', 'file3'), shell=True)
        for d in ['a', 'b', 'c']:
          subprocess.call('program2 %s %s %s %s %s' %(d, 'file4', 'file5', 
            'file6', 'file7'), shell=True)
      abProduct = list(itertools.product(range(0, 10), range(0, 10)))
      pool = multiprocessing.Pool(processes=numProcessors)
      pool.map(functionB, abProduct) 

次のエラーが発生します。

Exception in thread Thread-1:
Traceback (most recent call last):
  File "/usr/lib64/python2.6/threading.py", line 532, in __bootstrap_inner
    self.run()
  File "/usr/lib64/python2.6/threading.py", line 484, in run 
    self.__target(*self.__args, **self.__kwargs)
  File "/usr/lib64/python2.6/multiprocessing/pool.py", line 255, in _handle_tasks
    put(task)
PicklingError: Can't pickle <type 'function'>: attribute lookup __builtin__.function fa
iled

functionA の内容は重要ではなく、エラーは発生しません。functionB をマップしようとするとエラーが発生するようです。このエラーを取り除くにはどうすればよいですか? また、このコードを Python 2.6 で並列化する最良の方法は何ですか?

4

1 に答える 1

18

この動作が見られる可能性が最も高い理由は、プール、オブジェクト、および関数を定義する順序によるものです。multiprocessingスレッドを使用するのとまったく同じではありません。各プロセスは、環境のコピーを生成してロードします。プロセスで使用できないスコープで関数を作成したり、プールの前にオブジェクトを作成したりすると、プールは失敗します。

まず、大きなループの前に 1 つのプールを作成してみてください。

(minI, maxI, iStep, minJ, maxJ, jStep, a, b, numProcessors) = sys.argv
pool = multiprocessing.Pool(processes=numProcessors)
for i in range(minI, maxI, iStep):
    ...

次に、ターゲット callable を動的ループの外に移動します。

def functionB(a, b):
    ...

def main():
    ...

この例を考えてみましょう...

壊れた

import multiprocessing

def broken():
    vals = [1,2,3]

    def test(x):
        return x

    pool = multiprocessing.Pool()
    output = pool.map(test, vals)
    print output

broken()
# PicklingError: Can't pickle <type 'function'>: attribute lookup __builtin__.function failed

働く

import multiprocessing

def test(x):
    return x

def working():
    vals = [1,2,3]

    pool = multiprocessing.Pool()
    output = pool.map(test, vals)
    print output

working()
# [1, 2, 3]
于 2012-07-02T03:42:33.263 に答える