2017-11-20 6 views
1

私はPython Multiprocessing.poolについて簡単に質問しています。ここに私のコードです:ループ内でのmultiprocessing.poolの使用とターゲット機能の更新

import multiprocessing as mp 

info =999 
def func(x): 
    global info 
    print info 
    return x**3 

pool = mp.Pool() 
for i in range(2): 
    print "Iteration: ", i 
    results = pool.map(func, range(1,10)) 
    print "Value of info", info 
    info += 1 
    print results 
    print "Iteration", i, "End" 
    print 

、出力は次のようになります。2回目の反復では、999は私がグローバル変数の情報を更新するにはどうすればよいの代わりに1000の再印刷されて、なぜ私が疑問に思って

999 
999 
999 
999 
999 
999 
999 
999 
999 
999 
999 
999 
999 
999 
999 
999 
999 
999 
Iteration: 0 
Value of info 999 
[1, 8, 27, 64, 125, 216, 343, 512, 729] 
Iteration 0 End 

Iteration: 1 
Value of info 1000 
[1, 8, 27, 64, 125, 216, 343, 512, 729] 
Iteration 1 End 

2番目の反復で1000が印刷されるようにしますか?どうもありがとうございます!

+0

うーん、私ドン」 2回目の反復では999が印刷されますが、1000が表示されます。さらに、 'info - = 1'を使用しているので、2回目の反復で' info == 998'を期待します。 –

+0

申し訳ありませんが、コードはinfo + = 1でなければなりません。したがって、合計1899個が印刷されます。しかし、私がforループの情報を更新したとき、私は最後の999が1000であると予想しました.funcは情報を出力するので、 – Ksun46

+1

基本的に、各プロセスには独自のグローバルセットがあります。状態を共有する場合は、[ドキュメントのオプション](https://docs.python.org/2/library/multiprocessing.html#sharing-state- between-processes)をお読みください。共有状態は、自明ではない提案です。 'multiprocessing'は本質的に、' subprocess'モジュールを包むスレッド型のインターフェースです。文字通り、別々のPythonプロセスが各作業者ごとに作成されるため、マルチ*処理* –

答えて

1

コメントは既に説明済みです。私はもう少し説明してくれると思います。

multiprocessingモジュールを使用すると、要求されたプロセス数あたりの新しいプロセスがpoolに作成されます。デフォルトはmultiprocessing.cpu_count()で計算されます。

あなたが書いたスクリプトがA.pyで、プロセスAが作成されたとします。 Aが新しいプロセスを作成するとき、それはAの子プロセスと呼ばれます。これらの子プロセスは、最初にAという同じグローバル変数を持ちます。

ただし、各子プロセスは個別の有効範囲を持つため、ある子プロセスの変数infoを変更しても、他の子プロセスのinfoの値には影響しません。親プロセスAの値には影響しません。

簡単な解決策は、各子プロセスに、親プロセスAに必要な変更をinfoとして報告するように指示することです。つまり、mapの各子プロセスは結果として-1を返し、親プロセスAはそれ自身のスコープで更新を集約します。分散コンピューティングでは、これはパラメータサーバ設計と呼ばれます。

理想的な世界では、本当に欲しいのは、スコープとメモリを共有するスレッディングです。しかし、Global Interpreter LockのためにPythonスレッドが非常に複雑になることがあります。あなたが興味を持っている場合は、これについていくつかのGoogleの検索を行うことができます。


コードを誤って読んでいました。午前2時に私の心の中で、私は子供の中でinfoの修正を読んで、親で印刷しています。実際にはそれは逆です。

ポイントが変更されていることが正しいことは、プロセス間で共有されていないことです。モジュールの作成時に機能がpickledであるため、子プロセスでを使用してinfoにアクセスすると、子プロセスは変更を認識しません。あなたは、あなたがそうのように、関数の引数としてそれをダイナミックinfoを送信する必要がhttp://grahamstratton.org/straightornamental/entries/multiprocessing

での読むことができます:

import multiprocessing as mp 

def dual_input(t): 
    info, x = t 
    print info 
    return x**3 

def main(): 
    info =999 
    pool = mp.Pool(2) 
    for i in range(2): 
     print "Iteration: ", i 
     results = pool.map(dual_input, zip([info]*9, range(1,10))) 
     print "Value of info", info 
     info += 1 
     print results 
     print "Iteration", i, "End" 
     print 


if __name__ == '__main__': main() 

上記のコードを印刷:

Iteration: 0 
999 
999 
999 
999 
999 
999 
999 
999 
999 
Value of info 999 
[1, 8, 27, 64, 125, 216, 343, 512, 729] 
Iteration 0 End 

Iteration: 1 
1000 
1000 
1000 
1000 
1000 
1000 
1000 
1000 
1000 
Value of info 1000 
[1, 8, 27, 64, 125, 216, 343, 512, 729] 
Iteration 1 End 
+0

ありがとう、あなたは答えます。だから上記のコードの面では、私は子スレッドがグローバル変数 "情報"を変更しないと思います。しかし、プロセスAは反復中に "info"を1だけインクリメントします。しかし、2回目の反復では、子プロセスは "info"という初期値(999)に固執します。そのため、999が印刷されています。これは正しいですか? – Ksun46

+0

@ Ksun46更新を参照してください。 – Mai

関連する問題