2016-07-24 17 views
0

Python documentation on multiprocessingには、関数の作業を並列化する例が多数あります。私は、クラスに含まれている関数についてもこれを行うことができると想定していました。ただし、次の例は機能しません。 現在のプロセス番号の2の乗算を計算するプロセスが生成されます。オブジェクト内で計算された値を報告することはできますが、ジョブの終了後に計算された値を取得しようとすると、コンストラクタで設定された値が返されます。Pythonのマルチプロセッシングを使用する関数の代わりにクラス内の関数を呼び出す

クラス定義

import multiprocessing 


class MyClass(): 

    def __init__(self,runname): 
     self.runname = runname 
     self.output = 0 



    def calculate(self,input): 
     self.output = input*2 
     print "Reporting from runname %s, calculation yielded %s" % (self.runname,self.output) 


    def getOutput(self): 
     return self.output 

コードオブジェクトを呼び出す:

objectList = [] #Store objects 
jobList = [] #Store multiprocessing objects 

#Run the workers in 4 parallel processes 
for i in range(4): 

    thisRunname = 'Worker:%s' % i 
    thisInstance = MyClass(thisRunname) 

    p = multiprocessing.Process(target=thisInstance.calculate, args=(i,)) 

    jobList.append(p) 
    p.start() 
    objectList.append(thisInstance) 

for thisJob in jobList: #Wait till all jobs are done 
    thisJob.join() 

print "Jobs finished" 

for thisInstance in objectList: 
    print "Worker %s calculated %s " % (thisInstance.runname,thisInstance.getOutput()) 

この出力:しようとしたとき

Reporting from runname Worker:0, calculation yielded 0 
Reporting from runname Worker:1, calculation yielded 2 
Reporting from runname Worker:2, calculation yielded 4 
Reporting from runname Worker:3, calculation yielded 6 
Jobs finished 
Worker Worker:0 calculated 0 
Worker Worker:1 calculated 0 
Worker Worker:2 calculated 0 
Worker Worker:3 calculated 0 

だから計算機能は、問題なく生成でき計算された値を取得するck 0、コンストラクタで設定された値。

私が紛失しているキーコンセプトはありますか?self.output値はどのように取得できますか?

+1

たぶんこれらは、(各サブプロセスは、MyClassのの.OUTPUTの独自のコピーを更新し、したがって、メインプロセスの出力が影響されません)に役立つかもしれません:http://stackoverflow.com/questions/16244745/how-to-use-classes-with- python-マルチプロセッシング、http://stackoverflow.com/questions/32666559/cannot-change-class-variables-with-multiprocessing-process-object-in-python3 – mkaran

答えて

1

Processクラスによって提供されるシリアライゼーションは一方通行です。それはあなたがそれを与えるtargetargsをシリアル化しますが、何も自動的に戻って来ません。あなたはProcess ESを作成するときに

だから、multiprocessingモジュールの漬物(target sはインスタンスのメソッドをバインドされているので)あなたが作成したMyClassインスタンスと、それぞれが子プロセスのいずれかでそれをunpickle化されます。これは、それぞれの子供があなたが期待するように計算を行う理由です。

しかし、インスタンスの子プロセスのバージョンへの変更は、これまでに戻って、メインプロセスにコピーされません。単にそれを行うメカニズムはありません。最後に、子プロセスが終了するとインスタンスが破棄されます。親プロセスのインスタンスMyClassは更新されないため、calculated 0というメッセージが表示されます。

関連する問題