Select Language

AI Technology Community

8.1、マルチスレッドとは何か、Pythonマルチスレッドプログラミング

早くも20世紀60年代には、プロセスの概念が登場しました。しかし、プロセスはリソースの所有者であり、プロセスの作成、破棄、スケジューリングのコストは比較的高いため、軽量プロセスへの需要が生まれました。

20世紀80年代になると、スレッドが登場しました。プロセスに似て、スレッドは独立して実行できますが、使用するコストはプロセスよりもはるかに小さいです。

スレッドは一般的にプログラム、データ、スレッド制御ブロックを含み、そのうちスレッド制御ブロックは以下の情報を含みます:

  1. スレッド状態。

  2. スレッドが非実行状態のとき、その前回の実行終了時のプロセッサ状態、主にレジスタの状態。

  3. スタック情報。


スレッドは独立したスケジューリングと割り当ての基本単位であり、スレッド切り替えに消費されるリソースは比較的少ないです。マルチコアシステムでは、マルチスレッドは完全に並行して実行でき、これによりハードウェアの計算能力を完全に発揮することができます。同一プロセス内のスレッドは多くのリソースを共有します。例えば、ファイル、タイマーなどです。そのため、スレッド通信は非常に便利です。

スレッド状態

スレッドは異なる状態にあることができ、時間の経過とともに、スレッドは異なる状態間を移行します。スレッドには5つの状態があり、それぞれ新規作成、就緒、実行、ブロック、終了です。

図1に描かれているのは、スレッドがこれらの状態間を遷移する様子です。

スレッド状態遷移図
図1 スレッド状態遷移図


最初はスレッドを作成します。この新しく作成されたスレッドは「新規作成」状態にあり、これはすべてのスレッドの起点です。スレッドはこの状態では、エントリ関数、スタックのサイズなど、様々な設定を行うことができます。

操作1は、アプリケーションがそのスレッドを起動したことを表しています。このとき、スレッドは「就緒」状態に入ります。就緒状態のスレッドはまだ実際には実行されていませんが、実行するためのすべての条件を満たしています。

操作2は、オペレーティングシステムがそれにプロセッサリソースを割り当てたことを表しています。これで、スレッドは実行を開始し、新しい「実行」状態に切り替わります。

操作3は、スレッドが実行中に問題に遭遇し、一時的に実行を続けることができなくなったことを表しています。例えば、ファイルデータを読み取ろうとしたが、そのデータがまだシステムに入力されていない場合、オペレーティングシステムはそのスレッドをスケジューリングして「ブロック」キューに入れます。このとき、そのスレッドに割り当てられたプロセッサリソースは解放され、他の「就緒」状態のスレッドが使用できるようになります。

操作4は、スレッドが必要とするリソースが準備され、このスレッドが実行できるようになったことを表しています。

操作5は、実行中のあるスレッドがオペレーティングシステムによって就緒キューにスケジューリングされたことを表しています。プロセッサリソースが限られているため、「就緒」状態のスレッドの数はプロセッサの数よりもはるかに多い可能性があります。したがって、任意の時点で実行可能なスレッドの一部のみが実行されます。しかし、一部のスレッドが常に実行され、他のスレッドが待機状態になっていることは不合理です。そのため、オペレーティングシステムは定期的に実行中の一部のスレッドをスケジューリングして処理し、これにより空いたプロセッサを他の待機中のスレッドが使用できるようにします。

操作6は、スレッドが自ら終了するか、強制的に終了させられることを表しています。自ら終了するとは、スレッドコードの実行が完了することであり、この方法は比較的エレガントです。強制終了とは、外部コードがスレッドの実行を強制的に停止させることです。例えば、メインスレッドが終了すると、そのプロセス内のすべてのスレッドは強制的に終了します。強制終了は、一部の実行結果が保存される前に失われる可能性があります。自ら終了するのはシャットダウンに似ており、強制終了は停電に似ています。

操作7は強制終了です。

メインスレッド

プロセス内で最初に起動されるスレッドはメインスレッドであり、以下の特徴を持っています:

  • 他のすべてのスレッドはメインスレッドによって直接または間接的に作成されます。私たちはスレッドツリーを描くことができ、メインスレッドはツリーの根であり、他のスレッドはツリー上のノードです。

  • メインスレッドが終了すると、プロセスが終了し、そのプロセス内の他のすべてのスレッドは強制的に終了します。


私たちがよく言う、プロセスは少なくとも1つのスレッドを含むという場合、この少なくとも含まれるスレッドはメインスレッドです。

また、後の章では、いくつかのスレッド関連の概念が頻繁に登場します。ここでは、これらの概念を簡単に説明します。

  • スレッドID:すべてのスレッドには独自のIDがあり、Pythonのすべてのオブジェクトが独自のIDを持っているように。異なるスレッドのIDは異なります。

  • 親スレッド:メインスレッドを除いて、他のすべてのスレッドには親スレッドがあります。この親スレッドは、そのスレッドを作成したスレッドです。プログラムが起動するとき、メインスレッドのみが存在し、このスレッドが他のスレッドを起動することがあります。これらの新しく起動されたスレッドの親スレッドはメインスレッドです。

Pythonにおけるスレッド

Python言語は自然にスレッドをサポートしており、特別なソフトウェアパッケージを別途インストールする必要はありません。

Pythonシステムには、2つのスレッド関連のパッケージが付属しています。1つはthreadで、ユーザーにスレッドのエントリ関数として関数を提供することを要求します。もう1つのパッケージはthreadingで、入力としてthreading.Threadクラスを派生したインスタンスオブジェクトを要求します。これら2つのパッケージは提供するインターフェース関数が異なるだけで、内部のスレッド概念は同じです。後でそれぞれについて説明します。


post
  • 10

    item of content
プロセスはリソースを分配する単位であり、スレッドはオペレーティングシステムがスケジューリングできる最小の単位です。
通常、プロセスには少なくとも1つのスレッドが含まれ、複数のスレッドがある場合はその中にメインスレッドが含まれます。同じプロセス内のすべてのスレッドはシステムリソースを共有しますが、それぞれが独立したスタック、レジスタ環境、およびローカルストレージを持っています。
マルチスレッドの利点は、複数のタスクを同時に実行できることです。システムに複数の計算ユニットがある場合、複数のスレッドはそれぞれの計算ユニットで並行して動作することができ、これによりシステムの処理効率が大幅に向上します。
多くの場合、プロセスはスレッドよりも大きい単位であり、通常1つのプロセスは複数のスレッドを含むことができます。プロセスの隔離効果はスレッドよりも優れているため、マルチプロセスを使用するとマルチスレッドよりも安全です。ただし、マルチプロセスの欠点はマルチスレッドよりもスケジューリングが重く、効率が低いことです。