2012-03-25 50 views
4

編集:これはPythonのバグであることを確認しました。バグhttp://bugs.python.org/issue10332(私は新しいバグを提出しましたが、それに対応して、管理人が私に10332を指摘しました)。 Pythonのソースリポジトリからプロジェクトディレクトリにマルチプロセッシングディレクトリをコピーしました。テストケースは正しく動作しました。maxtasksperchildを使ったPythonマルチプロセッシング

maxtasksperchildパラメータを削除しない限り、このシンプルなプログラムはうまくいきません。私は間違って何をしていますか?私はそれを実行すると

from multiprocessing import Pool 
import os 
import sys 

def f(x): 
    print "pid: ", os.getpid(), " got: ", x 
    sys.stdout.flush() 
    return [x, x+1] 

def cb(r): 
    print "got result: ", r 

if __name__ == '__main__': 
    pool = Pool(processes=1, maxtasksperchild=9) 
    keys = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 
    result = pool.map_async(f, keys, chunksize=1, callback=cb) 
    pool.close() 
    pool.join() 

は、私が取得:

$ python doit.py 
pid: 6409 got: 1 
pid: 6409 got: 2 
pid: 6409 got: 3 
pid: 6409 got: 4 
pid: 6409 got: 5 
pid: 6409 got: 6 
pid: 6409 got: 7 
pid: 6409 got: 8 
pid: 6409 got: 9 

そして、それがハングアップします。つまり、10番目の要素を処理する新しいワーカは生成されませんでした。別の端末で

は、私は以下を参照してください。

$ ps -C python 
    PID TTY   TIME CMD 
6408 pts/11 00:00:00 python 
6409 pts/11 00:00:00 python <defunct> 

これは(Ubuntuのパッケージからインストール)2.7.2+のpythonを実行しているのUbuntu 11.10で行われます。

+0

これはPythonのバグだと思います。私がpool.close()を呼び出すと(pool.join()を呼び出す前に呼び出さなければならないと書かれています)、フラグpool._stateをCLOSEに設定します。 Pool._handle_workers関数は、新しいワーカープロセスを起動するために、そのフラグが 'RUN'であることに依存します。 pool.close()が呼び出されるまで約10秒間map_async呼び出し後にスリープ状態になることがあります。私はおそらく、Pythonにバグを報告します。 – user188012

+0

私はこれを確認することができますhevaiour。 python 2.7.2を使用して、maxtasksperchild = 1で同じ問題に直面しました。すべてのタスクが成功裏に完了した後、finall pool.join()でスクリプトが停止し、すべての子プロセスのゾンビ()を残しました。プール作成からこのパラメータを削除する - 問題を解決しました。 –

+0

これはこれまでに解決されましたか? – user3467349

答えて

-2

私はPythonでマルチスレッドを使用することはありませんが、私はあなたがこの行にmaxtasksperchild = 10を作りたいと思います。その変更後のpool = Pool(processes=1, maxtasksperchild=9)、出力は次のようになります。

pid: 8436 got: 1 
pid: 8436 got: 2 
pid: 8436 got: 3 
pid: 8436 got: 4 
pid: 8436 got: 5 
pid: 8436 got: 6 
pid: 8436 got: 7 
pid: 8436 got: 8 
pid: 8436 got: 9 
pid: 8436 got: 10 
got result: [[1, 2], [2, 3], [3, 4], [4, 5], [5, 6], [6, 7], [7, 8], [8, 9], [9, 10], [10, 11]] 
+0

あなたも9と同じ出力を得ていると聞いてよかったです。しかし、あなたが書いたものは私の質問に答えるものではありません。 maxtasksperchild = 10は、必要なワーカープロセスの再作成がないために機能します。なぜmaxtasksperchild = 9は動作しませんか? – user188012

0

は、一つの処理は、タスクの最大数を実行する意味maxtasksperchild

0

この問題はpython3で修正されました。

pid: 18316 got: 1 
pid: 18316 got: 2 
pid: 18316 got: 3 
pid: 18316 got: 4 
pid: 18316 got: 5 
pid: 18316 got: 6 
pid: 18316 got: 7 
pid: 18316 got: 8 
pid: 18316 got: 9 
pid: 18317 got: 10 
got result: [[1, 2], [2, 3], [3, 4], [4, 5], [5, 6], [6, 7], [7, 8], [8, 9], [9, 10], [10, 11]]