Pythonの並列・並行・非同期の処理ライブラリ

超特急の備忘録(=書きなぐり)です,想像的な内容も含まれておりますのでご注意ください.

並列/並行/非同期の処理のおさらい

マルチ・プロセス (並列処理)

  • 複数CPUコア使える,たぶん,CPUコア内で別スレッドとしても起動可能じゃないかと.つまり,CPUをフルに使って高速化するためにはマルチプロセスを使うべきかと.

Cons

  • CPUをフルに使用する最も最良の方法だが,メモリ共有できない
  • つまり,Threadingと違い,引数渡し,返り値受け取りの工夫が多分に必要

    その他

  • 既存コードからの拡張には,他の手法に比べ,大幅な書き直しが結構必要だろう,特にクラス使用のオブジェクト志向プログラミングでは,メソッドがフィールド変数を参照しているだろうが,それら値を使う事はできない(たぶん,できるなら誰か教えて頂きたい,キューやManagerでかきなおす??)
  • 既存のクラスも使えるだろうが,既存のパイプラインに流す事はPipeを使えばできるかもしれないが,壊れやすいらしい.よって,独立したメモリ確保(引数渡しの変数,返り値の受け取り変数,クラスや関数のインスタンスは各CPUコア用に分離が必要になるのだろう)

マルチ・スレッド(並行処理)

  • 使用できるコア数1らしい,よって,cpu_count()メソッドで取得した「CPU跨いだ全スレッド数」分だけThreadを起動してしまうと,むしろ効率が悪くなる模様.

    用途

    非同期より楽に並列化したい場合.スレッド数が極小に限られているもの限定かと.

  • lightな多重処理:非同期手法を要検討.
  • CPUフルに使用した処理時間の短縮:マルチプロセス
  • 非同期に仕事が移ったので,スレッド手法を選ぶ理由はかなり減ったかと.

    用途例

  • GUI.内部処理にしかスレッドが処理していなければ,ユーザからGUIへの操作は受け付けられない(GUIアプリがフリーズした感じ).GUIから内部処理に別スレッド起動すれば,GUIパーツ(e.g.ボタン)押したときのグラフィックの変化といった応答がある.
  • 1Coreに積んでいるスレッド機構に仕事振り分けて効率化できそうなケース.(かなり限定的?)

非同期(Non-Blocking / Async)

  • 並列化影響範囲が基本1プロセス内だろう(?)
  • 上記の通り,スレッドの多重化は速度低下の危険.改善するため,ある程度処理したら次の処理へと切り替える事で効率的にノンブロック(Nonフリーズ)で多数のリスクエストを処理する方法が好まれだしたもよう.(Webなんかで)

    vsスレッド

    • Cons: スレッドに比べ,処理切り替えのタイミングを自身で決定しなければならない.
    • Cons: 並列処理が,Thread走らせてしまえば(1)以後ノータッチで(2)短い処理で終わる場合はスレッドの方が向いているだろう.

      用途

      Webリクエストのような,処理数が読めない多量並行処理が要求される対象

ライブラリ一覧

主なPythonライブラリは次の通り

Major?

  • concurrent.futures
    • 記事は少ない(2018)が筆者はこちらを積極的に使用していきそう
  • multiprocessing : マルチプロセス用
  • Thread : マルチスレッド用
  • asyncio : NonBlocking/非同期用

Minor?

記事少ないため実用用途にはMajor分類のを利用した方がよいだろう

  • Joblib : 使用している記事をあまり見かけない

ライブラリの詳細MEMO

concurrent.futures

  • Python3.2から追加

  • Threadモジュに比べ,pool機構があるため,マルチスレッドの複数起動はこちらの方が効率良い?

  • Windowsでの開発においてmultiprocessingが開発中のアプリ本体のインスタンスが複数生成されたのに比べ,こちらでは1つで収まった.

    ボトルネック

  • CPUバウンド

    • 数値計算,画像処理など高負荷処理で,別処理(e.g. GUI)へ移れない.
  • I/Oバウンド

    • テープデバイスといった遅い装置の読み書き中にblock