web-dev-qa-db-ja.com

PythonマルチプロセッシングモジュールのThreadPoolとPoolの違いは何ですか

ThreadPoolモジュールのPoolmultiprocessingの違いは何ですか。コードを試してみると、これが主な違いです。

from multiprocessing import Pool
import os, time

print("hi outside of main()")

def hello(x):
    print("inside hello()")
    print("Proccess id: ", os.getpid())
    time.sleep(3)
    return x*x

if __== "__main__":
    p = Pool(5)
    pool_output = p.map(hello, range(3))

    print(pool_output)

次の出力が表示されます。

hi outside of main()
hi outside of main()
hi outside of main()
hi outside of main()
hi outside of main()
hi outside of main()
inside hello()
Proccess id:  13268
inside hello()
Proccess id:  11104
inside hello()
Proccess id:  13064
[0, 1, 4]

「ThreadPool」の場合:

from multiprocessing.pool import ThreadPool
import os, time

print("hi outside of main()")

def hello(x):
    print("inside hello()")
    print("Proccess id: ", os.getpid())
    time.sleep(3)
    return x*x

if __== "__main__":
    p = ThreadPool(5)
    pool_output = p.map(hello, range(3))

    print(pool_output)

次の出力が表示されます。

hi outside of main()
inside hello()
inside hello()
Proccess id:  15204
Proccess id:  15204
inside hello()
Proccess id:  15204
[0, 1, 4]

私の質問は:

  • 「outside __main __()」がPoolで毎回実行されるのはなぜですか?

  • multiprocessing.pool.ThreadPoolは新しいプロセスを生成しませんか?新しいスレッドを作成するだけですか?

  • もしそうなら、threadingモジュールだけでなくmultiprocessing.pool.ThreadPoolを使用することの違いは何ですか?

ThreadPoolの公式ドキュメントはどこにも見当たりませんが、どこで見つけられるか手伝ってもらえますか?

49
ozn

multiprocessing.pool.ThreadPoolは、multiprocessing.Poolと同じように動作しますが、プロセスの代わりにスレッドを使用してワーカーロジックを実行する点のみが異なります。

あなたが見る理由

hi outside of main()

multiprocessing.Poolで複数回印刷されるのは、プールが spawn 5つの独立したプロセスになるためです。各プロセスは独自のPythonインタープリターを初期化し、モジュールをロードして、最上位のprintが再び実行されるようにします。

これは、spawnプロセス作成メソッドが使用されている場合にのみ発生することに注意してください(Windowsでのみ使用可能なメソッド)。 fork one(Unix)を使用すると、スレッドに関して1回だけメッセージが出力されます。

multiprocessing.pool.ThreadPoolは実装が完了していないため文書化されていません。テストとドキュメントがありません。 ソースコード で実装を確認できます。

次の自然な質問は、スレッドベースのプールをいつ使用し、プロセスベースのプールをいつ使用するかです。

経験則は次のとおりです。

  • IOバウンドジョブ-> multiprocessing.pool.ThreadPool
  • CPUバウンドジョブ-> multiprocessing.Pool
  • ハイブリッドジョブ->ワークロードに依存します。プロセスの分離がもたらす利点により、通常multiprocessing.Poolを好む

Python 3では、 concurrent.future.Executor プールの実装を確認できます。

63
noxdafox