52

私はPythonでマルチプロセッシングを初めて使用し、2つの関数を非同期で呼び出すためにプールまたはプロセスを使用する必要があるかどうかを判断しようとしています。私が持っている2つの関数はcurl呼び出しを行い、情報を2つの別々のリストに解析します. インターネット接続によっては、各機能にそれぞれ約 4 秒かかる場合があります。ボトルネックは ISP 接続にあり、マルチプロセッシングではあまり高速化されないことはわかっていますが、両方が非同期で開始されるとよいでしょう。さらに、これは私が Python のマルチプロセッシングを理解するための素晴らしい学習体験です。

Python multiprocessing.Pool: when to use apply, apply_async or map? を読みました。それは役に立ちましたが、それでも私自身の質問がありました。

したがって、私ができる1つの方法は次のとおりです。

def foo():
    pass

def bar():
    pass

p1 = Process(target=foo, args=())
p2 = Process(target=bar, args=())

p1.start()
p2.start()
p1.join()
p2.join()

この実装について私が持っている質問は次のとおりです。1) 呼び出しプロセスが完了するまでブロックに参加するので、これは、p2 プロセスが開始される前に p1 プロセスが終了しなければならないことを意味しますか? .join() は pool.apply() および pool.apply_sync().get() と同じであり、現在実行中のプロセスが完了するまで親プロセスが別のプロセス(タスク)を起動できないことを常に理解していました。

他の選択肢は次のようになります。

def foo():
    pass

def bar():
    pass
pool = Pool(processes=2)             
p1 = pool.apply_async(foo)
p1 = pool.apply_async(bar)

この実装に関する質問は次のとおりです。1) pool.close()、pool.join() が必要ですか? 2) 結果を得る前に、pool.map() はそれらをすべて完了させますか? もしそうなら、それらはまだ非同期で実行されていますか? 3) pool.apply_async() は、pool.apply() で各プロセスを実行する場合とどのように異なりますか? 4) これは、Process を使用した以前の実装とどのように異なりますか?

4

2 に答える 2

38

リストした 2 つのシナリオは同じことを達成しますが、方法が少し異なります。

最初のシナリオでは、2 つの別個のプロセス (P1 と P2 と呼びます) を開始し、P1 runningfooと P2 runningを開始してbarから、両方のプロセスがそれぞれのタスクを完了するまで待機します。

2 番目のシナリオでは、2 つのプロセス (Q1 および Q2 と呼びます) を開始fooし、最初に Q1 または Q2 のいずれかで開始し、次にbarQ1 または Q2 のいずれかで開始します。その後、コードは両方の関数呼び出しが戻るまで待機します。

したがって、最終的な結果は実際には同じですが、最初のケースでは、異なるプロセスで実行することが保証されていfooますbar

同時実行性についての具体的な質問については、プロセスが完了するまで.join()a のメソッドは実際にブロックされますが、参加する前に P1 と P2 の両方を (最初のシナリオで) 呼び出したため、両方のプロセスが非同期で実行されます。ただし、インタープリターは P1 が終了するまで待ってから、P2 が終了するのを待ちます。Process.start()

プールのシナリオに関する質問については、技術的に使用するpool.close()必要がありますが、後で必要になる可能性があるものに依存します (範囲外になった場合は、必ずしも閉じる必要はありません)。pool.map()はまったく異なる種類の動物です。これは、一連の引数を同じ関数に (非同期で) プール プロセス全体に分散し、すべての関数呼び出しが完了するまで待ってから結果のリストを返すためです。

于 2013-08-11T20:17:32.230 に答える