スレッド (コンピュータ)
スレッド(thread)とは、CPU利用の単位。プロセスに比べて、プログラムを実行するときのコンテキスト情報が最小で済むので切り替えが速くなる。スレッドは、thread of execution(実行の脈絡)という言葉を省略したものである。
プログラミングの観点からみると、アプリケーションの処理の「実行の脈絡」は1つでないことが多い。これをシングルスレッドで実現しようとするとシグナルやタイマーを駆使してコーディングすることになる。また、複数のプロセスに分割してプロセス間通信で協調動作させるという方法もある。しかし、いずれの場合もそれらの機能を使うための余分な、本来のアルゴリズムと関係ないコーディングが必要となる。スレッドを使用したプログラミングは本来のアルゴリズムに集中しやすくなり、プログラムの構造が改善されるという効果がある。
スレッドとプロセスとタスク
計算機上で、複数の処理を同時に実行する(並行計算、マルチタスク)場合、処理を分割し、同時に実行する部分を指定する事が出来る、処理の分割の単位として、スレッドとプロセスがある。
新たなプロセスを動作させるためには、CPUやメモリ空間などを割り当てる必要がある。それぞれのプロセスは、割り当てられた資源内で独立して動く。しかし、この方法では、メモリ空間が独立してしまうため、独立したメモリ空間が不必要な場合、メモリの利用効率が悪い。プログラムによっては、共有メモリを利用しながら複数の処理を行ったほうが楽な場合があるため、プロセスの機能から必要なところだけを利用したものがスレッドであるとも言える。
1つのタスクは、1つ以上のプロセスから構成され、1つのプロセスは、1つ以上のスレッドから構成される。集合で表すと、スレッド ∈ プロセス ∈ タスクというようになる。しかし、この関係は環境によって異なる。例えば、リアルタイムOSでは、タスク ≒ スレッド、スレッド ∈ プロセス、である。しかし、タスクとプロセスの間に要素関係はない。
スレッドを使うことで、同一プロセス内の複数スレッドを同一メモリ空間上で実行でき、メモリ消費量などが軽減できるようになっている。しかし、このため、マルチスレッド処理のプログラミングにおいては、同じデータを複数のスレッドが同時に書き換えることによる不整合に注意し、排他制御を行う必要がある。 共有ライブラリ使用時には、その共有ライブラリがスレッドセーフ(リエントラント)になっているかどうか気をつけてプログラミングしなければならない。
ある処理を単一のスレッドのみを用いて動作させる環境もしくは手法をシングルスレッドという。対して、複数のスレッドが同時に動作することをマルチスレッドという。 プログラム(概ねプロセス)の開始時にはメインとなるスレッドが動作する。必要に応じてその他の処理をするスレッドを作り、実行させる事も出来る。
基本的に1つのCPUコアが、ある瞬間に同時に実行しているのは割り込み処理なども含めて1つのスレッド、1つのプロセス、1つのタスクである。同時マルチスレッディングなどはこの例外となる。テンプレート:See
ユーザースレッドとカーネルスレッド
ユーザ空間で実装されたスレッド機構をユーザースレッド、特に仮想機械上で動くものをグリーンスレッドと呼ぶ。ユーザースレッドの切り替えは、そのプロセスがユーザー空間で動作中にライブラリ内のスレッドスケジューラが行う。これは非常にオーバヘッドが小さく、しかも実装が簡単と言える。しかし、ひとつのプロセス内の複数のスレッドは常に1つだけが動作していることになり、マルチプロセッサシステムの恩恵を受けられない。また、あるスレッドがカーネル内で入出力待ちでスリープしてしまうと、全スレッドが入出力待ちとなってしまうという問題があった。すなわち、ユーザースレッドはあくまでもプログラミングの手法としてのみ意味を持ち、性能向上に寄与するものではない。
カーネル空間で実装されたスレッド機構をカーネルスレッドと呼ぶ。カーネルスレッドの切り替えはカーネルが行うため、マルチプロセッサシステムであれば同じプロセス内の複数のスレッドを並行して実行することもでき、どれかひとつのスレッドがスリープしても別のスレッドは処理を続行できる。しかし、カーネルスレッドは単にユーザー空間などのリソースを共有しているだけで、プロセス管理から見ればプロセスとほとんど変わりないため、オーバヘッド(コンテキストスイッチなど)もプロセス並みとなる。また、カーネルが全スレッドを管理するため、生成可能なスレッド数の制限がきつくなる。
ライトウェイトプロセス
ライトウェイトプロセス(Light Weight Process、LWP)または軽量プロセスとは、スレッドを複数並行して実行するためのカーネル内の機構。マルチプロセッシングにおいて、ひとつのプロセス内のスレッドを複数個同時に実行する仕組みである。カーネルスレッドとLWPを総称してネイティブスレッドと呼ぶこともある。
LWPは上述の2つの方式を組み合わせたもので、SolarisやSVR4.2MPで導入されたスレッド機構である。プログラミング上いくつでもスレッドを生成できるとしても、並列実行できるのはプロセッサ数までである。従って、カーネルスレッド方式のように全スレッドをカーネルが制御するのは無駄が大きい。そこでカーネルはLWPというスレッドを実行するオブジェクトを管理し、LWPが適当なユーザースレッドを選択して実行する。LWPの個数はプロセス当たりの上限(全プロセッサ数+α)が設定されているため無駄が少なくなり、ユーザースレッドはメモリなどが許す限り生成可能となる。また、ユーザースレッド間の切り替えをユーザー空間で行うため、オーバヘッドはユーザースレッドとカーネルスレッドの中間になる。
LWPはCライブラリ内でスレッド作成の延長で必要に応じて作成される。Cライブラリ内のスレッドスケジューラが、ユーザースレッドとLWPのマッピングを行う。このマッピングを指して、LWP方式を「M対Nスレッド」と呼ぶことがある。つまり、ユーザープロセス内のM個のスレッドとカーネル内のN個のLWPがマッピングを切り換えながら実行されることを意味している。
カーネルはLWPに関するシステムコールを提供しており、Cライブラリがそれを使用する(ユーザーにも公開されているが、一般に直接使うことはほとんどない)。LWPはコンテキストスイッチの対象として扱われるため、LWP方式のオペレーティングシステムではプロセス制御ブロックの一部がLWP毎のデータ構造になっている。
また、LWPとユーザースレッドを固定的に結びつけることもでき、これを「結合スレッド」と呼ぶ(一般のスレッドは「非結合スレッド」)。
ユーザーインターフェイススレッド
テンプレート:Main グラフィカルユーザインタフェースにおいては、デッドロックにまつわる複雑さを回避するためUIを操作するスレッドを1つに統一し、その上でワーカーデザインパターンを採用するという手法がよく採用される。