1. ホーム
  2. python

[解決済み] Pythonはマルチスレッドに対応していますか?実行時間を短縮できますか?

2022-10-05 20:36:47

質問

Pythonでマルチスレッドが動作するのかどうか、少し混乱しています。

私はこのことについて多くの質問があったことを知っていますし、それらの多くを読みました、しかし、私はまだ混乱しています。私は自分自身の経験から知っていますし、他の人がここ StackOverflow で彼ら自身の答えや例を投稿するのを見て、マルチスレッドは確かに Python で可能であることを知りました。では、なぜ誰もがPythonはGILによってロックされており、一度に1つのスレッドしか実行できないと言い続けるのでしょうか?明らかに動作しているのですが。それとも、私がここで得ていないいくつかの区別があるのでしょうか?

多くの投稿者/回答者は、マルチコアを使用しないため、スレッドが制限されていることにも言及し続けています。しかし、私は、マルチコアは同時に動作するため、まだ有用であり、したがって、複合ワークロードをより速く完了させることができると言います。つまり、そうでなければなぜPythonスレッドモジュールが存在するのでしょうか?

更新しました。

これまでのすべての回答ありがとうございました。私が理解したところでは、マルチスレッドは一部の IO タスクでのみ並列に実行され、CPU 拘束のマルチコア タスクでは一度に 1 つだけ実行できるということです。

これが実用上どのような意味を持つのか、私にはまったくわからないので、マルチスレッドにしたい種類のタスクの例だけを挙げます。たとえば、非常に長い文字列のリストをループ処理し、各リスト項目で基本的な文字列操作を行いたいとします。リストを分割し、各サブリストを新しいスレッドでループ/文字列コードに処理させ、結果をキューで送り返すと、これらのワークロードはほぼ同時に実行されるでしょうか?最も重要なことは、これは理論的にスクリプトを実行するのにかかる時間を速めるのでしょうか?

別の例として、4 つの異なるスレッドで PIL を使用して 4 つの異なる画像をレンダリングして保存することができ、画像を 1 つずつ処理するよりも高速になるでしょうか。正しい用語が何であるかよりも、この速度コンポーネントが私が本当に疑問に思っていることだと思います。

私はまた、マルチプロセッシング モジュールについて知っていますが、私の現在の主な関心は、小規模から中規模のタスク負荷 (10-30 秒) であり、サブプロセスを開始するのが遅いことがあるので、マルチスレッドがより適切であると思います。

どのように解決するのですか?

GILはスレッド化を防ぐものではありません。GILが行うのは、Pythonのコードを一度に実行するスレッドが1つだけであることを確認するだけであり、制御は依然としてスレッド間で切り替わります。

GILが防ぐのは、複数のCPUコアや別々のCPUを使用してスレッドを並列に実行することです。

これはPythonのコードにのみ適用されます。C 拡張は、C コードの複数のスレッドと 1 つの Python スレッドが複数のコアにわたって実行できるように、GIL を解放することができ、実際にそうしています。これはカーネルによって制御される I/O にも適用され、例えば select() のようなカーネルによって制御される I/O にも適用され、Python はマルチスレッドのマルチコアのセットアップでネットワークイベントを合理的に効率的に処理できるようになります。

多くのサーバー展開では、複数の Python プロセスを実行し、OS がプロセス間のスケジューリングを処理して、CPU コアを最大限に活用するようにしています。また multiprocessing ライブラリ を使うことで、1つのコードベースと親プロセスから複数のプロセスに渡る並列処理を扱うことができます。

GILはCPythonの実装にのみ適用できることに注意してください。JythonとIronPythonは異なるスレッド実装(それぞれネイティブのJava VMと.NET common runtime threads)を使用しています。

あなたのアップデートに直接対処するために。スレッド化された Python コードは一度に 1 つのスレッドを実行するようにロックされているので、純粋な Python コードを使用して並列実行から速度向上を得ようとするどのタスクも、速度向上を見ることはできません。しかし、Cの拡張やI/O(PILやnumpyの操作など)を混ぜれば、どんなCのコードであれ、並列実行に 1 と並行して実行できます。

Python のスレッド化は、応答性の良い GUI を作成したり、I/O が Python コードよりもボトルネックになっている複数の短い Web リクエストを処理したりするのに適しています。計算集約的な Python コードの並列化には適していませんので、Python スレッドに固執してください。 multiprocessing モジュールを使用するか、専用の外部ライブラリに委譲します。