2013-04-03 8 views
11

これに相当するマルチプロセッシングを使用する簡単な方法はありますか? sim_listの要素は「シミュレーション」オブジェクト、実行()であるPythonマルチプロセッシング - オブジェクトのリストにクラスメソッドを適用する

for sim in sim_list: 
    sim.run() 

は、オブジェクトの属性を変更しないシミュレーションクラスのメソッドです。たとえば、

class simulation: 
    __init__(self): 
    self.state['done']=False 
    self.cmd="program" 
def run(self): 
    subprocess.call(self.cmd) 
    self.state['done']=True 

sim_listのすべてのsimは独立しているので、戦略はスレッドセーフである必要はありません。

私は以下のことを試みました。これは、引数がdeepcopyによって渡され、インプレースで変更されていないため、明らかに欠陥があります。あなたがやりたい

from multiprocessing import Process 

for sim in sim_list: 
    b = Process(target=simulation.run, args=[sim]) 
    b.start() 
    b.join() 
+3

ループ内のプロセスにjoin()したくない場合や、パラレルではなく、順番にプロセスを実行する場合があります。あなたの質問に答えるために、プロセスを開始するときにマルチプロセッシングとキューオブジェクトを送信し、完了したらキューに自分自身を置くことができます。 –

+0

join()についてのコメントはありません。キューの使用に関しては、どのように動作するはずです。私のsimオブジェクトは、とにかくdeepcopyを通過するつもりはありませんか? – calys

+0

@calys Windowsでは、メソッドをpickleしようとしているため、PicklingErrorを取得します。UNIXでは、「deepcopy」はありません。単に各プロセスが完全なアドレス空間の完全なコピーを取得します。いくつかの明示的なプロセス間通信によって、インスタンス内の状態の変化を置き換える必要があります。 @Bakuriuありがとうございます。 – Bakuriu

答えて

11

一つの方法は、あなたのコンピューティング・クラス(あなたのケースでsimulationProcessのサブクラスであるを持つことです。適切に初期化されると、このクラスのインスタンスは別々のプロセスで実行され、必要に応じてリストからそれらのグループを設定することができます。ここで

はあなたが上に書いたものの上に構築し、例を示します

import multiprocessing 
import os 
import random 

class simulation(multiprocessing.Process): 
    def __init__(self, name): 
     # must call this before anything else 
     multiprocessing.Process.__init__(self) 

     # then any other initialization 
     self.name = name 
     self.number = 0.0 
     sys.stdout.write('[%s] created: %f\n' % (self.name, self.number)) 

    def run(self): 
     sys.stdout.write('[%s] running ... process id: %s\n' 
         % (self.name, os.getpid())) 

     self.number = random.uniform(0.0, 10.0) 
     sys.stdout.write('[%s] completed: %f\n' % (self.name, self.number)) 

それからちょうどオブジェクトのリストを作成し、ループで各1を起動します。あなたはこれを実行すると、あなたがすべき

sim_list = [] 
sim_list.append(simulation('foo')) 
sim_list.append(simulation('bar')) 

for sim in sim_list: 
    sim.start() 

独自のプロセスで実行される各オブジェクトを参照してください。 Process.__init__(self)をクラス初期化の最初のものとして、他に先立って呼び出すことを忘れないでください。

もちろん、この例ではプロセス間通信は含まれていません。あなたの状況がそれを必要とする場合は、追加する必要があります(あなたの質問からあなたがそれを必要とするかどうかは明らかではありませんでした)。

このアプローチは私のためにはうまくいきますが、私は何の欠点も認識していません。私が見落とした隠れた危険を知っている人は、私に知らせてください。

こちらがお役に立てば幸いです。

+1

ありがとうございました。それは動作します:) – calys

+0

素晴らしい答え、ありがとう –