フォークとスレッドの違いは何ですか?


回答:


94

フォークは、現在のプロセスのコピーであり、同じコードセグメントを持つ真新しいプロセスを提供します。メモリイメージが変化すると(通常、これは2つのプロセスの動作が異なるため)、メモリイメージの分離(コピーオンライト)が行われますが、実行可能コードは同じままです。タスクは、プロセス間通信(IPC)プリミティブを使用しない限り、メモリを共有しません。

1つのプロセスは複数のスレッドを持つことができ、それぞれがプロセスの同じコンテキスト内で並行して実行されます。メモリおよびその他のリソースはスレッド間で共有されるため、共有データには、データの破損を防ぐためのいくつかのプリミティブおよび同期オブジェクト(ミューテックス条件変数セマフォなど)を介してアクセスする必要があります。


3
おそらく、「現在のプロセスのコピー」を子プロセスとして参照する必要があります。

1
ただし、テキストセグメントは(事実上)共有されることが多く、データセグメントでもコピーオンライトにすることができます。
JEキュー


76

フォーク

フォークは、古いプロセスまたは親プロセスとまったく同じように見える新しいプロセスにすぎませんが、それでも、プロセスIDが異なり、独自のメモリを持つ別のプロセスです。親プロセスは、子用に別のアドレススペースを作成します。親プロセスと子プロセスは同じコードセグメントを持っていますが、互いに独立して実行されます。

フォークの最も簡単な例は、Unix / Linuxのシェルでコマンドを実行する場合です。ユーザーがコマンドを発行するたびに、シェルは子プロセスをforkし、タスクが完了します。

forkシステムコールが発行されると、親プロセスに対応するすべてのページのコピーが作成され、OSによって子プロセス用の別のメモリロケーションにロードされますが、場合によってはこれは必要ありません。「exec」システムコールと同様に、execvは親プロセス自体のアドレス空間を置き換えるため、親プロセスページをコピーする必要はありません。

フォークについて注意すべき点は次のとおりです。

  • 子プロセスは独自の一意のプロセスIDを持ちます。
  • 子プロセスには、親のファイル記述子の独自のコピーが必要です。
  • 親プロセスによって設定されたファイルロックは、子プロセスによって継承されません。
  • 親プロセスで開いているセマフォはすべて、子プロセスでも開いている必要があります。
  • 子プロセスには、親のメッセージキュー記述子の独自のコピーが必要です。
  • 子供には独自のアドレス空間とメモリがあります。

スレッド

スレッドは軽量プロセス(LWP)です。伝統的に、スレッドは、残りの部分(データ、スタック、I / O、シグナル)を含むプロセスを持つ単なるCPU(および他のいくつかの最小状態)状態です。システムはプロセスの新しいシステム仮想メモリ空​​間と環境を初期化しないため、スレッドは新しいプロセスを「フォーク」または生成するよりもオーバーヘッドが少なくて済みます。プロセスフローを別のプロセッサで実行するようにスケジュールできるマルチプロセッサシステムで最も効果的ですが、並列処理または分散処理によって速度が向上しますが、I / Oのレイテンシを利用するユニプロセッサシステムや、プロセスを停止する可能性のあるその他のシステム機能にも効果があります。実行。

同じプロセスのスレッドは共有します:

  • プロセス指示
  • ほとんどのデータ
  • 開いているファイル(記述子)
  • シグナルとシグナルハンドラ
  • 現在の作業ディレクトリ
  • ユーザーおよびグループID

詳細については、こちらをご覧ください


2
プロセスは複数のスレッドを持つことができます。プロセス内のスレッドの1つがforkを呼び出す場合、forkされたプロセスには完全に複製されたメモリがありますが、呼び出し元のスレッドのみが新しいプロセスにありますか?
Michael


29

Dacavの答えは素晴らしいです、私はただすべてのスレッドモデルがあなたに真のマルチプロセッシングを与えるわけではないことを付け加えたかっただけです。

たとえば、Rubyのデフォルトのスレッド実装は、真のOS /カーネルスレッドを使用しません。代わりに、単一のカーネルスレッド/プロセス内のThreadオブジェクトを切り替えることで、複数のスレッドを模倣します。

これらのタイプの軽量スレッドはシングルコアでしか実行できないため、これはマルチプロセッサ/マルチコアシステムでは重要です。複数のスレッドを使用することによるパフォーマンスの向上はあまり得られません。

これが違いを生むもう1つの場所は、1つのスレッドがブロックする場合(I / Oを待機するか、ドライバーのIOCTLを呼び出す場合)、すべてのスレッドがブロックする場合です。

これは今日ではあまり一般的ではありません-ほとんどのスレッディング実装は、これらの問題に悩まされないカーネルスレッドを使用していますが、完全性のために言及する価値があります。

対照的に、forkは、元のプロセスの実行中に別の物理CPUで同時に実行可能な別のプロセスを提供します。一部の人々はIPCが自分のアプリにより適していると感じ、他の人々はスレッドを好む。

頑張って楽しんでね!マルチスレッドは、やりがいとやりがいがあります。


7
神経を打つための+1:「すべてのスレッドが真のマルチプロセッシングを提供するわけではない」
Dacav

5

スレッドは並列に実行される関数で、フォークは親を継承する新しいプロセスです。スレッドはタスクを並行して実行するのに適していますが、フォークは独立したプロセスであり、同時に実行されます。スレッドには競合状態があり、セマフォとロックまたはミューテックスを制御します。パイプは、フォークとスレッドの両方で使用できます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.