web-dev-qa-db-ja.com

フォークとスレッド

私は以前にアプリケーションでスレッド化を使用し、その概念をよく知っていましたが、最近、オペレーティングシステムの講義でfork()に出会いました。これはスレッド化に似たものです。

私はそれらの違いをグーグルで検索し、それを知った:

  1. フォークは、古いプロセスまたは親プロセスとまったく同じように見える新しいプロセスに他なりませんが、それでもプロセスIDが異なり、独自のメモリを持つ別のプロセスです。
  2. スレッドは、オーバーヘッドの少ない軽量プロセスです

しかし、私の心にはまだいくつかの質問があります。

  1. スレッド化とその逆よりもfork()を好むのはいつですか?
  2. 外部アプリケーションを子として呼び出したい場合、fork()またはスレッドを使用してそれを行う必要がありますか?
  3. グーグル検索をしているときに、スレッド内でfork()を呼び出すのは悪いことだという人がいます。なぜ人々は同じようなことをするときにスレッド内でfork()を呼び出したいのですか?
  4. 親プロセスと子プロセスが同時に実行されないため、fork()がマルチプロセッサシステムを利用できないのは本当ですか?

分岐アプローチとスレッドアプローチの主な違いは、オペレーティングシステムアーキテクチャの1つです。 Unixが設計された当時、フォークは、メインフレームおよびサーバータイプの要件に最もよく応える、簡単でシンプルなシステムでした。そのため、Unixシステムで普及しました。 MicrosoftがNTカーネルをゼロから再構築したとき、スレッドモデルに重点が置かれました。そのため、今日でも、フォークで効率的なUnixシステムとスレッドで効率的なWindowsには顕著な違いがあります。最も顕著なのは、Unixではプリフォーク戦略を使用し、Windowsではスレッドプーリングを使用するApacheで見ることができます。

特にあなたの質問に:

スレッド化とその逆よりもfork()を好むのはいつですか?

Unixシステムで、単にワーカーをインスタンス化するよりもはるかに複雑なタスクを実行している場合、または個別のプロセスの暗黙的なセキュリティサンドボックス化が必要な場合。

外部アプリケーションを子として呼び出したい場合、fork()またはスレッドを使用してそれを行う必要がありますか?

子が同じコードで親と同じタスクを実行する場合は、forkを使用します。より小さなサブタスクにはスレッドを使用します。別の外部プロセスがどちらも使用しない場合は、適切なAPI呼び出しで呼び出してください。

グーグル検索をしているときに、スレッド内でfork()を呼び出すのは悪いことだという人がいます。なぜ人々は同じようなことをするときにスレッド内でfork()を呼び出したいのですか?

完全には定かではありませんが、プロセスと多くのサブスレッドを複製するのは計算上かなり高価だと思います。

親プロセスと子プロセスが同時に実行されないため、fork()がマルチプロセッサシステムを利用できないのは本当ですか?

これは誤りです。forkは新しいプロセスを作成し、OSタスクスケジューラのプロセスで使用可能なすべての機能を利用します。

48

分岐したプロセスはヘビーウェイトプロセスと呼ばれ、スレッド化されたプロセスはライトウェイトプロセスと呼ばれます。

それらの違いは次のとおりです。

  1. 分岐したプロセスは子プロセスと見なされますが、スレッド化されたプロセスは兄弟と呼ばれます。
  2. 分岐したプロセスは親プロセスとコード、データ、スタックなどのリソースを共有しませんが、スレッドプロセスはコードを共有できますが、独自のスタックを持っています。
  3. プロセスの切り替えにはOSの助けが必要ですが、スレッドの切り替えは必要ありません
  4. 複数のプロセスの作成はリソースを大量に消費するタスクですが、複数のスレッドの作成はリソースをあまり消費しないタスクです
  5. 各プロセスは独立して実行できますが、一方のスレッドは別のスレッドのデータを読み書きできます。スレッドとプロセス 講義enter image description here
26
Selvaperumal

fork()は、既に述べたように、プロセスの新しいコピーを生成します。上記で言及されていないのは、後に続くexec()呼び出しです。これにより、既存のプロセスが新しいプロセス(新しい実行可能ファイル)に置き換えられます。したがって、fork()/exec()は、古いプロセスから新しいプロセスを生成する標準的な手段です。

例えばこれが、シェルがコマンドラインからプロセスを呼び出す方法です。プロセス(ls、たとえば)とシェルフォークを指定してから、lsを実行します。

これは、スレッド化とは非常に異なるレベルで動作することに注意してください。スレッドは、プロセス内で複数行の実行を実行します。分岐はnewプロセスを作成する手段です。

12
Brian Agnew