ここで質問されるスレッドには、4 つの異なるタイプがあります。
- バックグラウンド タスクを処理するためにカーネル自体によって作成されたスレッド。
fork()
syscallによって fork されたプロセス。
clone()
Linux syscallを使用してユーザーによって作成され、カーネルによって管理される pthread スレッド
- カーネル スケジューラの外部で完全に実行される「グリーン」スレッド
次の回答は、投稿で言及されている「ユーザーレベル」のスレッドが pthread の種類であり、「グリーン」の種類ではないことを前提としています。
編集: @Hristoは正しいと思います.OPは「グリーン」スレッドについて話しているか、2つを混同しています。
この回答は、で作成したスレッドについて話していることを前提としていますpthread_create()
。ユーザー空間によってスケジュールされ、カーネルに認識されない「グリーン」スレッドもあります。後世のためにここに私の答えを残します。
ユーザー スレッド == グリーン スレッド
いわゆる「グリーン スレッド」は、定義上、カーネルの関与なしに VM によって完全に処理されるスレッドです。
「ユーザーレベル」のカーネルはスレッドについて何も知らないため、プロセスは一度に 1 つのプロセッサ/コアしか使用しません。
右。
1 つのスレッドがブロッキング呼び出しを行うと、カーネルはスレッドの存在を認識しないため、すべてのスレッドが再びブロックされます。
いいえ。適切なプリミティブを使用している限り、ブロッキング呼び出しによってスレッドが待機キューに入れられ、別のグリーン スレッドが実行されます。
カーネルレベルのスレッドが作成されると、プロセスの .text(コード領域) はどのように変更されますか?
グリーンスレッドでは、それらはすべて同じコード領域を使用します。
さらに、他のすべての領域は同じままです (.bss、ヒープなど)。
はい。
ユーザースレッド == pthreads
「pthread_create()
ユーザースレッド」では、それらと「カーネル」スレッドの間にほとんど違いはありません。clone()
Linux カーネルは、システム コール を使用して、ユーザー レベルのスレッドを個別のカーネル プロセスとして実装します。clone()
親プロセスと同じメモリ空間を使用する新しいプロセスを作成しますが、親メモリのコピーfork()
を使用して新しいプロセスを作成します。
「ユーザーレベル」のカーネルはスレッドについて何も知らないため、プロセスは一度に 1 つのプロセッサ/コアしか使用しません。
いいえ、これは正しくありません。カーネルは、コンテキストの切り替えや、複数の CPU でさまざまなユーザーレベルのスレッドをスケジュールする機能などがあるという点で、他のプロセスと同じようにユーザーレベルのスレッドを管理します。
1 つのスレッドがブロッキング呼び出しを行うと、カーネルはスレッドの存在を認識しないため、すべてのスレッドが再びブロックされます。
いいえ、1 つのスレッドがブロックされても、他のスレッドは引き続き実行されます。繰り返しますが、これは pthread スタイルのスレッドの下にあります。
カーネルレベルのスレッドが作成されると、プロセスの .text(コード領域) はどのように変更されますか?
新しいスレッドが作成されると、そのスレッドは親のメモリ セグメンテーション テーブルを継承します。テキスト/コード ページ (およびその他の読み取り専用ページ) は読み取り専用としてマークされ、2 つのスレッドはスレッドの存続期間中メモリを共有します。すべての読み取り/書き込みページは、新しいスレッドによってそれらのセクションへの書き込みが行われるまで共有され、その時点でページは別の場所にコピーされます (コピー オン ライト)。
さらに、他のすべての領域は同じままです (.bss、ヒープなど)。
いいえ、ヒープページ、および読み取り専用としてマークされていないその他のもの (言及したスタックを含む) は、書き込まれるとすぐにコピーされます。.bss セクションについてはよくわかりませんが、実行時に初期化されるため、読み書きもできると思います。DATA は読み取り専用です。