2016-03-20 5 views
1

を理解します。これを行うために、私は作業しているコードの非常に単純なバージョンを作って、それを並行して動作させようとしました。私が読んだところによると、mp.Processを使うよりも私のプログラムには、poolを使う方が適しています。最終的には10と20のオブジェクト間で含まれていますは、私がどのようにPythonのマルチプロセッシングモジュールの仕事を理解しようとしていますシンプルなマルチプロセッシング・スクリプト

import time, os 
import multiprocessing as mp 

class Foo: 
    def __init__(self, ID): 
     self.ID = ID 

    def showID(self): 
     for k in range(0,4): 
      print('Foo #', self.ID, '\tID:', os.getpid(), '\tParent ID:', os.getppid()) 
      time.sleep(0.2) 

# MAIN 
if __name__ == '__main__': 

    print('parent process:', os.getppid()) 
    print('process id:', os.getpid()) 
    print(' ') 

    foos = [Foo(2), Foo(3)] 

    pool = mp.Pool(processes=2) 

    # Code below doesn't work 
    pool.apply_async(foos[0].showID,()) 
    pool.apply_async(foos[1].showID,()) 

リストfoosを:以下

は私が思いついたものです。メソッドFoo.showIDも結局何かを返すでしょう。私の目標は、彼らがpoolのプロセスの1つに派遣できるように、実行する時間が来たら、多くのタスク(foosメンバー)を送ることです。

私は上記のコードを実行すると、何も、つまりは起こりません。最初にparent processprocess idのみが表示されます。私はことにより、2つの最後の行を交換する場合:私はこのような何かに置き換える場合は、

parent process: 3380 
process id: 6556 

Foo # 2   ID: 6556  Parent ID: 3380 
Foo # 2   ID: 6556  Parent ID: 3380 
Foo # 2   ID: 6556  Parent ID: 3380 
Foo # 2   ID: 6556  Parent ID: 3380 
Foo # 3   ID: 6556  Parent ID: 3380 
Foo # 3   ID: 6556  Parent ID: 3380 
Foo # 3   ID: 6556  Parent ID: 3380 
Foo # 3   ID: 6556  Parent ID: 3380 

最後に:

pool.apply_async(foos[0].showID()) 
pool.apply_async(foos[1].showID()) 

それらの両方は、他の後のメイン処理1で実行されている

parent process: 3380 
process id: 4772 

Foo # 3   ID: 4772  Parent ID: 3380 
Foo # 2   ID: 6364  Parent ID: 4772 
Foo # 3   ID: 4772  Parent ID: 3380 
Foo # 2   ID: 6364  Parent ID: 4772 
Foo # 3   ID: 4772  Parent ID: 3380 
Foo # 2   ID: 6364  Parent ID: 4772 
Foo # 3   ID: 4772  Parent ID: 3380 
Foo # 2   ID: 6364  Parent ID: 4772 
pool.apply_async(foos[0].showID,()) 
pool.apply_async(foos[1].showID()) 

は私が予想される動作(と思う)を取得します

ここに何が起こっていますか? Fooクラスの中で定義されていない関数を使用しようとすると、同じ動作に気付きました。

答えて

1

apply_asyncは機能

あなたは括弧なしでfoos[0].showIDを使用する場合は、関数を渡して、それを呼び出していないが、

pool.apply_async(foos[0].showID()) 

を行うときは、最初に渡し、その後、foos[0].showID()を評価しているしているを受け取り、戻り値をapply_asyncの引数として返します。評価を終えるものはapply_asyncの呼び出し元であり、それは同期処理です。

それはやっと同等です:

foos[0].showID() 
pool.apply_async() 
foos[1].showID() 
pool.apply_async() 

あなたが実行するための非同期呼び出しを待っていないので、あなたの最初の試みが失敗しました。電話した後。

pool.apply_async(foos[0].showID,()) 
pool.apply_async(foos[1].showID,()) 

出力を待たずにプログラムが終了します。

最後に

pool.apply_async(foos[0].showID,()) 
pool.apply_async(foos[1].showID()) 

に相当します。

pool.apply_async(foos[0].showID,()) 
foos[1].showID() 

は1つの非同期呼び出しと1つの同期呼び出しを行いますので、それは一種の作品。

1

オリジナルコードの問題は、子プロセスが作業を行うのを待っていないことです。作業項目をスケジュールして終了し、プールが作業員を殺したとします。ジョブをスケジュールし、完了するのを待っているときに結果オブジェクトを返しておいてください。

import time, os 
import multiprocessing as mp 

class Foo: 
    def __init__(self, ID): 
     self.ID = ID 

    def showID(self): 
     for k in range(0,4): 
      print('Foo #', self.ID, '\tID:', os.getpid(), '\tParent ID:', os.getppid()) 
      time.sleep(0.2) 

# MAIN 
if __name__ == '__main__': 

    print('parent process:', os.getppid()) 
    print('process id:', os.getpid()) 
    print(' ') 

    foos = [Foo(2), Foo(3)] 

    pool = mp.Pool(processes=2) 

    results = [] 
    results.append(pool.apply_async(foos[0].showID,())) 
    results.append(pool.apply_async(foos[1].showID,())) 

    for result in results: 
     result.wait() 
+0

私は1つの回答のみを受け入れなければなりませんでしたが、この回答は結果を取り出す方法も示しています。ありがとう! – Iodestar

関連する問題