6

マルチプロセッサマシンでのposixスレッドの同時実行性について疑問があります。私はそれに関してSOで同様の質問を見つけましたが、決定的な答えは見つかりませんでした。

以下は私の理解です。私が正しいかどうか知りたいです。

  1. Posixスレッドはユーザーレベルのスレッドであり、カーネルはそれを認識しません。

  2. カーネルスケジューラは、Process(およびそのすべてのスレッド)をスケジューリング用の1つのエンティティとして扱います。実行するスレッドを選択するのはスレッドライブラリです。実行可能なスレッド間でカーネルによって指定されたCPU時間をスライスできます。

  3. ユーザースレッドは、さまざまなCPUコアで実行できます。つまり、スレッドT1とT2をProcess(T)で作成すると、T1はCpu1で実行でき、T2はCpu2で実行できますが、同時に実行することはできませ

私の理解が正しいかどうか教えてください。

ありがとう...

4

3 に答える 3

9

質問に「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つの方法は、pswith-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)、別の完全なプロセスが作成されるときに使用されるものとは異なります。

于 2012-04-10T13:20:38.033 に答える
5

pthread_createPOSIXは、で作成されたスレッドがプロセッサコアにどのようにスケジュールされるかを指定しません。これは実装次第です。

ただし、高品質の実装では次のことが期待されます。これは、現在のバージョンのLinuxの場合です。

  • スレッドは完全なカーネルスレッドであり、カーネルによってスケジュールされます
  • 同じプロセスのスレッドは、別々のプロセッサで同時に実行できます

つまり、番号が付けられた3つのステートメントはすべて、Linuxの現在の実装では間違っていますが、理論的には、POSIXに準拠した別の実装にも当てはまる可能性があります。

于 2012-04-10T13:24:42.280 に答える
0

ほとんどのPOSIX実装は、OSサポートを使用してスレッド機能を提供します。つまり、スレッドの管理に必要なシステムコールをラップします。そのため、スレッドの動作はreです。スケジューリングなどは、基盤となるOSによって異なります。

したがって、最新のOSでは次のようになります。

  1. POSIXスレッドを使用するプロセスは、複数のスレッドを使用する他のプロセスとカーネルとの違いはありません。

  2. カーネルスケジューラは、プロセスではなくスレッドをディスパッチします。「プロセス」は、多くの場合、コード、メモリ管理、クォータ、監査、およびセキュリティ権限はあるが実行はできない、より高いレベルの構成と見なされます。スレッドがそのコードを実行しない限り、プロセスは何もできません。そのため、プロセスが作成されると、「メインスレッド」が同時に作成されます。そうでない場合、何も実行されません。OSスケジューリングアルゴリズムは、スレッドが実行するプロセスをパラメータの1つとして使用して、次に実行する準備ができているスレッドのセットを決定する場合があります(1つのスレッドを同じプロセスのスレッドと交換する方が安価です)が、そうする必要はありません。

    実行可能なスレッド間でカーネルによって指定されたCPU時間をスライスすることは、それらを実行するコアよりも多くの準備ができているスレッドがある場合のOSタイマー割り込みの副作用です。定期的に頼らなければならないマシン(うーん!-私はこの用語が嫌いです)、「タイムスライシング」は過負荷と見なされるべきであり、CPUが多いか、作業が少ないはずです。スレッドは、理想的には、別のスレッドまたはIOドライバーによって通知された場合にのみ準備ができている必要があります。これは、OSタイマー割り込みが、まだ有用な作業を実行している可能性のある別のスレッドの代わりにスレッドを実行することを決定したためではありません。

  3. それらは同時に実行できます。2つのスレッドの準備ができていて、2つのコアがある場合、スレッドは2つのコアにディスパッチされます。それらが同じプロセスからのものであるかどうかは関係ありません。

于 2012-04-10T13:50:20.400 に答える