1. ホーム
  2. パイソン

[解決済み】マルチプロセッシングの Pool.map() で <type 'instancemethod'> を pickle できない。)

2022-04-05 04:16:04

質問

を使おうとしています。 multiprocessing 's Pool.map() 関数を使って同時に作業を分担しています。以下のコードを使用すると、正常に動作します。

import multiprocessing

def f(x):
    return x*x

def go():
    pool = multiprocessing.Pool(processes=4)        
    print pool.map(f, range(10))


if __name__== '__main__' :
    go()

ところが、もっとオブジェクト指向で使ってみると、うまくいかない。出てくるエラーメッセージは

PicklingError: Can't pickle <type 'instancemethod'>: attribute lookup
__builtin__.instancemethod failed

下記をメインプログラムとした場合に発生します。

import someClass

if __name__== '__main__' :
    sc = someClass.someClass()
    sc.go()

で、以下は私の someClass クラスがあります。

import multiprocessing

class someClass(object):
    def __init__(self):
        pass

    def f(self, x):
        return x*x

    def go(self):
        pool = multiprocessing.Pool(processes=4)       
        print pool.map(self.f, range(10))

どなたか、この問題の原因、または簡単な回避方法をご存知ですか?

解決方法は?

問題は、マルチプロセシングではプロセス間でスリングするためにものをピックルする必要があり、バインドメソッドはピックルできないことです。 回避策は(それを "easy" と考えるかどうかは別として)、そのようなメソッドを pickle できるようにするためのインフラをプログラムに追加し、そのインフラを コピー_レグ 標準ライブラリのメソッドです。

例えば、Steven Bethard氏の寄稿した このスレッド (このスレッドの最後の方) では、完全に実行可能な方法のひとつとして copy_reg .