2017-09-15 11 views
0

私のプログラムは、コマンドラインから整数値を受け取るchallengesという1つの引数を取ります。私は、自己定義された方法generationchallengesの値を渡すことによってmultiprocessingを使用したい:クラスGenParentClassマルチプロセッシングを使用してメソッドに引数を渡すことはできません.Pool

import multiprocessing 

gen = generator.GenParentClass() 
mlp = multiprocessing.Pool(processes=multiprocessing.cpu_count()) 
X, y = mlp.imap_unordered(gen.generation, [args.challenges]) 

方法generationをこの単純なシグネチャがあります。

def generation(self, num): 
    #some stuff 

はしかし、私はこのエラーを取得します:

Traceback (most recent call last): 
    File "experiments.py", line 194, in <module> 
    X, y = mlp.imap_unordered(gen.generation, [args.challenges]) 
    File "/anaconda/lib/python2.7/multiprocessing/pool.py", line 668, in next 
    raise value 
cPickle.PicklingError: Can't pickle <type 'instancemethod'>: attribute lookup __builtin__.instancemethod failed 

この問題の解決方法はわかりません。すべて私は正しいようです!どんな助けもありがとう。

+0

'gen'はクラスですか、それとも1つのインスタンスですか? – martineau

+0

@martineau 'gen'は' GenParentClass'クラスのインスタンスです – Medo

+0

'generation()'メソッドを使ってそれをスタンドインクラスのインスタンスにすると、別のエラーが発生します: 'ValueError:アンパックする値が足りません(期待された2、1を得た)。質問を編集し、問題を再現するのに十分なコードを追加してください。 [** _最小限で完全で検証可能なサンプルを作成する方法_ **](https://stackoverflow.com/help/mcve)を参照してください。また、メインタスクのコードの適切な場所に 'if __name__ == '__main __':'を追加しました。 – martineau

答えて

1

モジュールは、引数をimap_unorderedにシリアル化します()。関数gen.generationは(クラス内で定義された)インスタンスメソッドであることが判明しています。つまり、ピクルできないため、エラーになります。

編集:ここでは、クラスの外の関数を定義可能な回避策であり、itertoolsからpartialを用いて充填される関数に追加の引数(複数可)を追加しますで

import multiprocessing 
from functools import partial 

class GenParentClass(object): 
    a = None 
    b = None 
    def __init__(self, a, b): 
     self.a = a 
     self.b = b 

# define this outside of GenParentClass (i.e., top level function) 
def generation(num, x, y): 
    return x+y+num 

gen = GenParentClass(3, 5) 
mlp = multiprocessing.Pool(processes=multiprocessing.cpu_count()) 
R = mlp.imap_unordered(partial(generation, x=gen.a, y=gen.b), [1,2,3]) 
print([r for r in R]) # prints "[9, 10, 11]" 

詳細情報酸洗い能力はhereです。

functoolsの詳細についてはhereをご覧ください。

編集2:あなたはmultiprocess.Poolを使用して、関数定義は、修飾された変数名self.aself.bを使用している場合は、クラスの外の関数を書き換えることなく、これを行うことができますが、出力を取得することはできません、と状態gen2の値は変更されません(関数呼び出しの目的を破る)。

gen2 = GenParentClass(4, 6) 
p = {} 
for key in range(5): 
    p[key] = multiprocessing.Process(target = GenParentClass.altgen, args = (gen2, key,)) 
    p[key].start() 

for key in p: 
    p[key].join() 
+0

正しい。クラスを変更せずに回避策がありますか? – Medo

+0

変数 'a'と' b'が 'altgen'関数で修飾されているという条件で' multiprocessing.Process'を使ってこれを行うことができましたが(上記2の編集を参照)、問題はあなたが取り出せないということです出力。 – Ken

関連する問題