次の図は、プロセスのメモリレイアウトを示しています。
:
誰かforks()
と新しい人が割り当てられたら、task_struct
プロセスのアドレスはどうなりますか?つまり、プロセスがあると仮定すると、次の図が維持されます。それではフォークを作るとしましょう。どうしたの?
答え1
答え2
プロセスが分岐すると、Linuxは非常に少量のコピーを実行し、書き込み中にコピー方式を使用します。この書き込み中のコピーは、両方のプロセス(親と子)が両方とも読み取っている場合はまったく同じメモリブロックから読み取られることを意味します。そのうちの1つがそのメモリに書き込まれると、メモリはコピーされ、共有されなくなります。
今、プログラムはこのようなことが起こっているかどうかわからない。これは、カーネルが各プロセスのページテーブルを維持するためです。プロセスが「メモリ0xbeefにアクセスしたい」と言うと、カーネルはそれを物理メモリの実際の場所に再マップします。これは、プログラムがこれらのアドレスを変数に格納するため、プログラムが分岐したときにメモリ内のデータが移動されたかどうかがわからないため、必要です(変数に格納されているすべてのアドレスは引き続き有効でなければなりません)。
これがスワップが機能する理由です。カーネルはデータを保持する物理メモリをインポートしてディスクに保存できますが、プログラムはまだアドレス0xbeefを参照し、カーネルはそれを変換します。
したがって、カーネルがコピーする絶対最小値は、このアドレスマッピングを実行するページテーブルと作業構造(オープンファイル、プロセスステータス、保留中の信号など)です。
答え3
答え4
アドレス空間全体が複製されます。つまり、図はフォーク後の2つのプロセスを示しています。これらのプロセスは、それぞれ異なる方法で物事を変更するので、異なる。