質問に「Linux」タグを付けたので、Linuxでの標準のpthreadの実装に従って回答します。OSではなくVM/言語レベルでスケジュールされている「グリーン」スレッドについて話している場合、答えはほとんど正しいです。しかし、以下の私のコメントはLinuxpthreadに関するものです。
1)Posixスレッドはユーザーレベルのスレッドであり、カーネルはそれを認識しません。
いいえ、これは確かに正しくありません。Linuxカーネルとpthreadsライブラリは、連携してスレッドを管理します。カーネルは、コンテキストスイッチング、スケジューリング、メモリ管理、キャッシュメモリ管理などを実行します。もちろん、ユーザーレベルで行われる他の管理もありますが、カーネルがないと、pthreadの能力の多くが失われます。
2)カーネルスケジューラは、Process(およびそのすべてのスレッド)をスケジューリング用の1つのエンティティとして扱います。実行するスレッドを選択するのはスレッドライブラリです。実行可能なスレッド間でカーネルによって指定されたCPU時間をスライスできます。
いいえ、カーネルは各プロセススレッドを1つのエンティティとして扱います。プロセス(およびプロセスの優先順位)を考慮したタイムスライシングに関する独自のルールがありますが、各サブプロセススレッドはスケジュール可能なエンティティです。
3)ユーザースレッドは異なるCPUコアで実行できます。つまり、スレッドT1とT2をProcess(T)で作成すると、T1はCpu1で実行でき、T2はCpu2で実行できますが、同時に実行することはできません。
いいえ。マルチスレッドプログラムでは、同時実行が期待されます。そのため、同期とミューテックスが非常に重要であり、プログラマーがマルチスレッドプログラミングの複雑さに耐えるのはそのためです。
これを証明する1つの方法は、ps
with-L
オプションの出力を調べて、関連するスレッドを表示することです。 ps
通常、複数のスレッド化されたプロセスを1行にラップし-L
ますが、カーネルにはスレッドごとに個別の仮想プロセスIDがあることがわかります。
ps -ef | grep 20587
foo 20587 1 1 Apr09 ? 00:16:39 java -server -Xmx1536m ...
対
ps -eLf | grep 20587
foo 20587 1 20587 0 641 Apr09 ? 00:00:00 java -server -Xmx1536m ...
foo 20587 1 20588 0 641 Apr09 ? 00:00:30 java -server -Xmx1536m ...
foo 20587 1 20589 0 641 Apr09 ? 00:00:03 java -server -Xmx1536m ...
...
Linuxスレッドがまだこれを行うかどうかはわかりませんが、歴史的にpthreadはclone(2)
システムコールを使用してそれ自体の別のスレッドコピーを作成していました。
fork(2)とは異なり、これらの呼び出しにより、子プロセスは、メモリスペース、ファイル記述子のテーブル、シグナルハンドラーのテーブルなど、実行コンテキストの一部を呼び出しプロセスと共有できます。
これはfork(2)
、別の完全なプロセスが作成されるときに使用されるものとは異なります。