フォークはプロセスのメモリレイアウトにどのような影響を与えますか?

フォークはプロセスのメモリレイアウトにどのような影響を与えますか?

次の図は、プロセスのメモリレイアウトを示しています。

:

誰かforks()と新しい人が割り当てられたら、task_structプロセスのアドレスはどうなりますか?つまり、プロセスがあると仮定すると、次の図が維持されます。それではフォークを作るとしましょう。どうしたの?

答え1

分岐後、同じプログラムのコピーが2つ作成されます。カーネルはすべてをコピーできます。アドレス空間または書き込み中のコピー。後者の場合、テキストとデータ部分は常に2つのプロセスで共有でき、子プロセスがスタックを変更する必要がある場合はスタックがコピーされます。

答え2

プロセスが分岐すると、Linuxは非常に少量のコピーを実行し、書き込み中にコピー方式を使用します。この書き込み中のコピーは、両方のプロセス(親と子)が両方とも読み取っている場合はまったく同じメモリブロックから読み取られることを意味します。そのうちの1つがそのメモリに書き込まれると、メモリはコピーされ、共有されなくなります。

今、プログラムはこのようなことが起こっているかどうかわからない。これは、カーネルが各プロセスのページテーブルを維持するためです。プロセスが「メモリ0xbeefにアクセスしたい」と言うと、カーネルはそれを物理メモリの実際の場所に再マップします。これは、プログラムがこれらのアドレスを変数に格納するため、プログラムが分岐したときにメモリ内のデータが移動されたかどうかがわからないため、必要です(変数に格納されているすべてのアドレスは引き続き有効でなければなりません)。
これがスワップが機能する理由です。カーネルはデータを保持する物理メモリをインポートしてディスクに保存できますが、プログラムはまだアドレス0xbeefを参照し、カーネルはそれを変換します。

したがって、カーネルがコピーする絶対最小値は、このアドレスマッピングを実行するページテーブルと作業構造(オープンファイル、プロセスステータス、保留中の信号など)です。

答え3

各プロセスには固有のアドレス空間( "仮想メモリ")、アドレスは同じままですが、変換テーブルから別のメモリアドレスを参照できます(修正時)。プロセスの観点から見ると、使用して見ているアドレスには何の変化もありません。

答え4

アドレス空間全体が複製されます。つまり、図はフォーク後の2つのプロセスを示しています。これらのプロセスは、それぞれ異なる方法で物事を変更するので、異なる。

関連情報