[解決済み] Pythonはマルチスレッドに対応していますか?実行時間を短縮できますか?
質問
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
モジュールを使用するか、専用の外部ライブラリに委譲します。
関連
-
[解決済み] Pythonには文字列の'contains'サブストリングメソッドがありますか?
-
[解決済み] Pythonで現在時刻を取得する方法
-
[解決済み] 最小限の驚き」と「変更可能なデフォルトの引数
-
[解決済み] Python 3で「1000000000000000 in range(1000000000000001)」はなぜ速いのですか?
-
[解決済み] モジュールの関数名(文字列)を使って、モジュールの関数を呼び出す。
-
[解決済み] 最近のPythonでカスタム例外を宣言する適切な方法?
-
[解決済み】ネストされたディレクトリを安全に作成するには?
-
[解決済み】Pythonに三項条件演算子はありますか?
-
[解決済み】2つの辞書を1つの式でマージする(辞書の和をとる)には?)
-
[解決済み] virtualenvsはどこに作成するのですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] Djangoで2つの日付の間を選択する
-
[解決済み] Spyderを仮想環境で動作させるには?
-
[解決済み] dict を txt ファイルに書き、それを読み取る?
-
[解決済み] SQLAlchemy: 日付フィールドをフィルタリングする方法は?
-
[解決済み] データフレームをソートした後にインデックスを更新する
-
[解決済み] サブフォルダからのインポートモジュール
-
[解決済み] CSVデータを処理する際、1行目のデータを無視する方法を教えてください。
-
[解決済み] Pythonによる一対のクロスプロダクト [重複] (英語)
-
[解決済み] Flaskで非同期タスクを作る
-
[解決済み] Pythonでリストが空かどうかをチェックする方法は?重複