Python 3でのマルチプロセッシングvsマルチスレッディングvs asyncio


105

Python 3.4では、マルチプロセッシング/スレッディング用のいくつかの異なるライブラリがあることを発見しました:マルチプロセッシング vs スレッディング vs asyncio

しかし、どちらを使用するか、または「推奨されるもの」かわかりません。彼らは同じことをしますか、それとも異なりますか?もしそうなら、どれが何のために使用されますか?コンピューターでマルチコアを使用するプログラムを書きたいのですが。しかし、どのライブラリを学ぶべきかわかりません。


回答:


79

それらは(わずかに)異なる目的および/または要件を対象としています。CPython(典型的なメインラインのPython実装)には依然としてグローバルインタープリターロックがあるため、マルチスレッドアプリケーション(現在の並列処理を実装する標準的な方法)は最適ではありません。これmultiprocessing に優先される理由threadingです。ただし、すべての問題が[ほぼ独立した]部分に効果的に分割されるとは限らないため、大量のプロセス間通信が必要になる場合があります。そのため、一般的にはmultiprocessing優先さthreadingれません。

asyncio(この手法は、Pythonだけでなく、他の言語やフレームワークでも使用できます(Boost.ASIOなど)。これは、並列コード実行の必要なしに、多数の同時ソースからの大量のI / O操作を効果的に処理する方法です。 。したがって、これは特定のタスクの単なるソリューション(確かに良いものです)であり、一般的な並列処理ではありません。


7
3つすべては並列処理を実現できない場合がありますが、それらはすべて並行(非ブロッキング)タスクを実行できます。
sargas

65

[素早い回答]

TL; DR

正しい選択をする:

最も一般的な並行性の形式について説明しました。しかし問題は残ります-いつどれを選ぶべきですか?それは本当にユースケースに依存します。私の経験(および読書)から、私はこの疑似コードに従う傾向があります:

if io_bound:
    if io_very_slow:
        print("Use Asyncio")
    else:
        print("Use Threads")
else:
    print("Multi Processing")
  • CPUバウンド=>マルチプロセッシング
  • I / Oバウンド、高速I / O、接続数の制限=>マルチスレッド
  • I / Oバウンド、遅いI / O、多くの接続=> Asyncio

参照


[ ]:

  • 長い呼び出しメソッド(つまり、スリープ時間または遅延I / Oを含むメソッド)がある場合、最適な選択はasyncioTwisted、またはTornadoのアプローチ(コルーチンメソッド)であり、単一スレッドで並行性として機能します。
  • asyncioの作品Python3.4以降。
  • トルネードツイステッドPython2.7以降で使用可能です
  • uvloopは超高速asyncioイベントループです(uvloopasyncio2〜4倍高速になります)。

[更新(2019)]:

  • Japranto GitHubは、uvloopベースの非常に高速なパイプラインHTTPサーバーです

だから私が要求するURLのリストを持っているなら、それはAsyncioを使う方が良いですか?
mingchau

1
@mingchau、はい、しかし、あなたの中から使用することができ、心に留めておくasyncio、あなたがawaitable関数から使用する場合request、ライブラリではなく、あなたがそのようなとして使用できることで、awaitable方法ではなくaiohttp、ライブラリまたは非同期要求およびなど
Benyamin Jafari

マルチスレッドまたは非同期に移行するために、slowIOとfastIOを拡張してください>?
qrtLs

@qrtLs SlowIOがある場合、AsyncIOは非常に役立ち、より効率的です。
Benyamin Jafari

1
@変数I / Oバウンドとは、プログラムがほとんどの時間をネットワーク接続、ハードドライブ、プリンター、スリープ時間のあるイベントループなどの低速デバイスとの通信に費やすことを意味します。したがって、ブロッキングモードでは、スレッドまたはasyncioのどちらかを選択できます。境界セクションが非常に遅い場合は、協調マルチタスク(asyncio)の方が適しています(つまり、リソースの不足、デッドロック、競合状態を回避します)
Benyamin Jafari

8

これが基本的な考え方です。

それはIO結合型?--------->使用asyncio

IT CPU-重いですか?----->使用multiprocessing

そうしないと ?---------------------->使用threading

したがって、IO / CPUの問題がない限り、基本的にスレッド化に固執します。


0

ではマルチプロセッシングあなたの計算を配布するために複数のCPUを活用します。各CPUは並列に実行されるため、複数のタスクを同時に効率的に実行できます。CPUにバインドされたタスクにはマルチプロセッシングを使用する必要があります。例は、巨大なリストのすべての要素の合計を計算しようとすることです。マシンに8つのコアがある場合、リストを8つの小さなリストに「カット」して、それらのリストのそれぞれの合計を別々のコアで個別に計算し、それらの数値を合計することができます。そうすることで、最大8倍のスピードアップが得られます。

ではスレッド複数のCPUは必要ありません。多くのHTTPリクエストをWebに送信するプログラムを想像してみてください。シングルスレッドのプログラムを使用した場合、各リクエストで実行(ブロック)を停止し、応答を待ち、応答を受信したら続行します。ここでの問題は、外部サーバーがジョブを実行するのを待機している間、CPUが実際に機能していないことです。それまでの間、実際に役立つ作業を行っていたかもしれません。修正はスレッドを使用することです-スレッドの多くを作成でき、それぞれがWebからのコンテンツのリクエストを担当します。スレッドの良い点は、スレッドが1つのCPUで実行されている場合でも、CPUが1つのスレッドの実行を「フリーズ」し、別のスレッドの実行にジャンプすることです(コンテキストスイッチングと呼ばれ、非決定的に常に発生します)。間隔)。 -スレッドを使用します。

asyncioは基本的にスレッドではなく、CPUではなく、プログラマー(または実際にはアプリケーション)として、コンテキストスイッチが発生する場所とタイミングを決定します。Pythonでは、awaitキーワードを使用して、コルーチン(asyncキーワードを使用して定義)の実行を一時停止します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.