フォークと実行はどのように機能しますか?

フォークと実行はどのように機能しますか?

私は経験がなく、ユーザーレベルからハードウェアに至るまでどのように解釈されるかに参加しようとしています。

したがって、コマンドがシェルでトリガーされると、その子プロセスはfork()継承され、exec()メモリにロードされ実行されます。

  1. 子プロセスに親プロセス(つまり元のプロセス)のすべての属性が含まれている場合、子プロセスには何が必要ですか?元のプロセスがメモリにロードされた可能性があります。
  2. この概念はUNIXのすべてのランチャーにfork適用されますか?execまた、シェルスクリプトが好きですか、それともコマンドが好きですか?シェル内蔵でも動作しますか?
  3. 時だ書き込み中のコピーコマンド/スクリプトを実行するにはどのような概念が使用されますか?

一度にあまりにも多くの質問をして申し訳ありませんが、どのようなコマンドの実行を考えると、これらの質問がすぐに思い浮かびます。

答え1

したがって、シェルでコマンドが実行されると、fork()は子プロセスを継承し、exec()は子プロセスをメモリにロードして実行します。

完全なものではなく。 fork()現在のプロセスを複製し、同じ子プロセスを作成します。 exec()新しくロードするプログラム現在のプロセスを入力し、既存のプロセスを置き換えます。

私の質問は次のとおりです

親プロセス(つまり元のプロセス)のすべての属性を含む場合、子プロセスには何が必要ですか?元のプロセスがメモリにロードされた可能性があります。

親プロセスがまだ終了したくないので必要です。新しいプロセスを開始し続けながら何かをしようとしています。

これらのフォークとexecの概念は、UNIXのすべてのランチャーに適用されますか?シェルスクリプトと同じですか、それともコマンド専用ですか?シェル内蔵でも動作しますか?

外部コマンドの場合、シェルはfork()そのコマンドが新しいプロセスで実行されるようにタスクを実行します。組み込み関数はシェルによってのみ直接実行されます。注目すべきもう1つのコマンドは、最初にシェルをexec呼び出さずにexec()外部プログラムにコマンドすることですfork()。これは、シェル自体が新しいプログラムに置き換えられ、プログラムが返されずに終了することを意味します。exec trueと言うと、/bin/trueシェルは交換され、すぐにシャットダウンされ、端末で何も実行されなくなり、閉じます。

書き込み中にコピーコンセプトを使用するときにコマンド/スクリプトを実行しますか?

石器時代には、fork()呼び出しプロセスのすべてのメモリを新しいプロセスにコピーする必要がありました。書き込み中のコピーは、両方のプロセスが同じメモリを共有し始め、両方のプロセスで書き込まれたページが必要な場合にのみコピーされるようにページテーブルを設定する最適化です。

答え2

  1. 一部のプログラムでは、子プロセスは1つのタスク(シリアルポートから読み取り、端末に書き込み)を実行し、親プロセスは引き続き別のタスク(端末から読み取り、シリアルポートに書き込み)を実行します。別の典型的な例は、発生する長期実行計算に対してチェックポイントを実行するサブプロセスです。ほとんどの場合、子プロセスはディレクトリの変更、シグナルハンドラのリセット、ファイル記述子のリセットなどのいくつかの設定を実行し、他のコードexecve()で自分自身を上書きするように呼び出します。
  2. fork()そしてexec()これはすべての実行可能ファイルに適用されます。実際には、argcとargv、パイプ、フォーク、execと共に、これはUnixを他のオペレーティングシステムと区別する要素です。 BSD、Plan 9、Linuxfork()などのいくつかの特殊化または一般化がありますが、原則は同じままです。vfork()rfork()clone()
  3. 記録中のコピーは実際にはユーザーには表示されず、サブプロセスの作成と実行を最適化する技術に近いです。呼び出しスタックとヒープ(割り当てられたメモリ、さらには静的malloc()またはグローバルスコープ変数を含む)は、「記録中のコピー」にすることができます。呼び出しによって子プロセスが生成されると、fork()カーネルは子プロセスが親プロセスとまったく同じメモリページ(ヒープとスタック)を持つように設定します。ハードウェア(メモリ管理デバイス)がヒープまたはスタックへの書き込みを検出すると、カーネルは新しい物理メモリページを取得し、親プロセスのページを新しいページにコピーし、その新しいページを子プロセスのスタックまたはヒープにマッピングします。 。これは、カーネルがサブプロセスのスタックとヒープを完全にコピーするよりもページマッピングを設定するのに少ない時間を費やすため、最適化を構成します。

答え3

子プロセスに親プロセス(つまり元のプロセス)のすべての属性が含まれている場合、子プロセスには何が必要ですか?元のプロセスがメモリにロードされた可能性があります。

この質問に対する答えは、厳格なメモリ制約の下で動作する必要があり、メモリ/アドレス空間で一度に1つの実行プロセスしかなかった初期のUnix実装を見るとわかります。

マルチタスクは、あるプロセスをディスクに交換し、別のプロセスを交換することによって行われます。

forkシステムコールはほぼ同じです。あるプロセスをディスクに置き換えますが、別のプロセスを置き換えるのではなく、メモリ内コピーに別のプロセスIDを指定して返します。exec結局のところ、今はプロセスが別の実行可能ファイルを入力することを決定する適切な時期です。

fork+execしたがって、ビルドプロセスには実際に目立つオーバーヘッドはありません。とにかくプロセスをディスクに置き換える必要がありますが、とにかく前のプロセスイメージは利用可能なメモリ位置にあります。

利用可能なメモリとメモリ管理デバイスの数が増加し、複数のメモリプロセスが増加するにつれて、最初に無視することができた分岐コストは、一部のアーキテクチャではさらに面倒な問題になりました。こうしてvfork誕生しました。

答え4

これをできるだけ簡単に理解するためにたとえ話を使いましょう。パイを焼く!

私たちは料理本を拾って読み始め、自家製クラストを持つイチゴルバーブパイ(私の好きなもの)を決めました。卵と果物を除いて必要なほとんどすべてが台所にありましたが、私たちは農場に住み、果物も季節だったので問題になりませんでした。問題は、オーブンが壊れて、すべてを行う時間が不足しているということでした。 1人以上いるといいじゃないですか?

fork() が救出されます。私は今二人です。私たちは両方ともキッチンに行き、パイクラスターを作り始めました。こんな。それでは、フォークからの戻りを見てみましょう。私は大きな数字を得て、彼はゼロを得た。だから私は台所に行き、彼は鶏小屋と庭に行きました。オーブンを通過したら、再度 fork() して戻り値を調べます。あっ、0が出ました。私が壊れたオーブンを眺めながら、彼は小麦粉を食べ続けました。ドアを開けたのに光がなくてドアを閉めました。オーブンを修理する方法を知っていますか?

exec() が構造体に来ます。ツールベルトの電圧計に手を差し伸べると、電球が診断を実行して電源を確認し、ブレーカーが作動して簡単に固定できました。サーキットブレーカパネルに近づくと、ルバーブを取る男が見えました。こんな!私はチョコレートシルクパイが好きです。

関連情報