Slide 1

Slide 1 text

プロセスの生成 コピーオンライトを使った fork編 Dec. 28th, 2024 Satoru Takeuchi X: satoru_takeuchi 1

Slide 2

Slide 2 text

はじめに ● 過去動画ではfork時に親プロセスのメモリをコピーする単純なモデルで説明してい た ● 本動画ではLinuxにおけるforkの実際の挙動を説明する ○ 実際は仮想記憶の機能を応用してメモリのフルコピーをしていない ○ そのためforkの実行コストは低い ● 事前に必要な知識 ○ fork関数についての基礎知識 ○ 仮想記憶、ページテーブルについての基礎知識 ● 関連動画 ○ Linuxのメモリ管理入門 プロセスごとに違う世界を見せる仮想記憶 ○ 仮想アドレスから 物理アドレスにはどうやって変換するの ? ○ プロセスの生成 fork編 2

Slide 3

Slide 3 text

おさらい: 仮想アドレス空間とページテーブル 3 プロセスAの仮想アドレス 0 200 物理メモリ 0 プロセスAのメモリ 500 600 100 200 300 400 700 仮想アドレス 物理アドレス 0-100 100-200 100-200 200-300 ページサイズ プロセスAのページテーブル (カーネルメモリ上に存在 ) 100 ページテーブルエントリ 物理アドレス

Slide 4

Slide 4 text

forkの挙動 ● これまでの説明 ○ 親プロセスのメモリを子プロセスにコピー ● 実際のもの ○ 親プロセスと子プロセスのページテーブルだけをコピー ○ 親子プロセスがメモリを共有 4

Slide 5

Slide 5 text

fork後のメモリマップ 5 プロセスAの仮想アドレス 0 200 物理メモリ 0 プロセスA,Bのメモリ 500 600 100 200 300 400 700 仮想アドレス 物理アドレス 0-100 100-200 100-200 200-300 プロセスAのページテーブル 100 物理アドレス 0 200 100 プロセスAからforkした プロセスBの仮想アドレス 仮想アドレス 物理アドレス 0-100 100-200 100-200 200-300 プロセスBのページテーブル コピー

Slide 6

Slide 6 text

疑問: fork後にメモリに書き込みができないのでは? 6 プロセスAの仮想アドレス 0 200 物理メモリ 0 プロセスA,Bのメモリ 500 600 100 200 300 400 700 仮想アドレス 物理アドレス 0-100 100-200 100-200 200-300 プロセスAのページテーブル 100 物理アドレス 0 200 100 プロセスBの仮想アドレス 仮想アドレス 物理アドレス 0-100 100-200 100-200 200-300 プロセスBのページテーブル

Slide 7

Slide 7 text

解決策: コピーオンライト技術を使う ● ページテーブルエントリには書き込み可否を決められるフラグがある ● 親子プロセスが共有するメモリ(ページ)は書き込み不可にする ● メモリへの書き込みが発生した場合は以下のような処理をする 1. 書き込みと同時にページフォールト例外発生 2. ページフォールトハンドラが書き込まれたページをコピー 3. ページテーブルエントリを変更 4. 例外から復帰する ● 書き込み時にメモリをコピーするので「Copy-on-Write(CoW)」と呼ばれる 7

Slide 8

Slide 8 text

fork後のメモリマップ with 書き込み可能ビット 8 プロセスAの仮想アドレス 0 200 物理メモリ 0 プロセスA,Bのメモリ 500 600 100 200 300 400 700 仮想アドレス 物理アドレス 書き込み可能 0-100 100-200 × 100-200 200-300 × プロセスAのページテーブル 100 物理アドレス 0 200 100 プロセスBの仮想アドレス 仮想アドレス 物理アドレス 書き込み可能 0-100 100-200 × 100-200 200-300 × プロセスBのページテーブル

Slide 9

Slide 9 text

fork後に書き込み発生 9 プロセスAの仮想アドレス 0 200 物理メモリ 0 プロセスA,Bのメモリ 500 600 100 200 300 400 700 仮想アドレス 物理アドレス 書き込み可能 0-100 100-200 × 100-200 200-300 × プロセスAのページテーブル 100 物理アドレス 0 200 100 プロセスBの仮想アドレス 仮想アドレス 物理アドレス 書き込み可能 0-100 100-200 × 100-200 200-300 × プロセスBのページテーブル 書き込み

Slide 10

Slide 10 text

当該ページは書き込み不可なのでページフォールト発生 10 プロセスAの仮想アドレス 0 200 物理メモリ 0 プロセスA,Bのメモリ 500 600 100 200 300 400 700 仮想アドレス 物理アドレス 書き込み可能 0-100 100-200 × 100-200 200-300 × プロセスAのページテーブル 100 物理アドレス 0 200 100 プロセスBの仮想アドレス 仮想アドレス 物理アドレス 書き込み可能 0-100 100-200 × 100-200 200-300 × プロセスBのページテーブル 書き込み ページフォールト 例外発生

Slide 11

Slide 11 text

ページフォールトハンドラがメモリをコピー 11 プロセスAの仮想アドレス 0 200 物理メモリ 0 プロセスAのメモリ 500 600 100 200 300 400 700 仮想アドレス 物理アドレス 書き込み可能 0-100 100-200 × 100-200 200-300 × プロセスAのページテーブル 100 物理アドレス 0 200 100 プロセスBの仮想アドレス 仮想アドレス 物理アドレス 書き込み可能 0-100 100-200 × 100-200 200-300 × プロセスBのページテーブル 書き込み プロセスA,Bのメモリ プロセスBのメモリ コピー

Slide 12

Slide 12 text

ページテーブルエントリを設定 12 プロセスAの仮想アドレス 0 200 物理メモリ 0 プロセスAのメモリ 500 600 100 200 300 400 700 仮想アドレス 物理アドレス 書き込み可能 0-100 100-200 〇 100-200 200-300 × プロセスAのページテーブル 100 物理アドレス 0 200 100 プロセスBの仮想アドレス 仮想アドレス 物理アドレス 書き込み可能 0-100 300-400 〇 100-200 200-300 × プロセスBのページテーブル 書き込み プロセスA,Bのメモリ プロセスBのメモリ コピー

Slide 13

Slide 13 text

CoWを使う嬉しさ ● forkの所要時間が削減できる ● forkによるメモリ使用量の増加が減らせる 13

Slide 14

Slide 14 text

まとめ ● fork()は仮想記憶を応用したコピーオンライト(CoW)技術を使っているため、高速、 かつ、メモリ使用量が少ない ● かっこいい 14