共有メモリを作成するためにmmap()を使用するとします。合計メモリサイズが4096であると仮定します。子プロセスを生成するためにfork()システムコールを使用する場合、子プロセスは同じメモリを使用しますか、それとも機能するには独自のメモリが必要ですか?
答え1
存在するfork()
親プロセスのメモリ空間が子プロセスに複製されます。最適化として、最新のオペレーティングシステムはCOW(記録中のコピー)を使用するため、サブプロセスの1つが変更を実行するまで、すべてのプライベートメモリがサブプロセスと共有されます。その後、影響を受けたメモリページがコピーされます。
子プロセスと親プロセスは異なるメモリ空間で実行されます。 fork() の時点では、両方のメモリ空間が同じ内容を持ちます。あるプロセスで実行されるメモリ書き込み、ファイルマッピング(mmap(2))、およびマッピング解除(munmap(2))は、他のプロセスには影響しません。
割り当てられたメモリを含む「両方のメモリ空間は同じ内容を持ちます」mmap()
。複製およびmmap()
/またはmunmap()
分岐されたメモリマップは、もはや他のプロセスに影響を与えません。
フォークMAP_SHARED
(またはLinux固有MAP_SHARED_VALIDATE
)以前にマップされたメモリのみがプロセス間で変更を伝播します。
MAP_SHAREDは
この地図を共有しています。マッピングの更新は、同じリージョンをマッピングする別のプロセスに表示され(ファイルサポートマッピングの場合)、デフォルトファイルに渡されます。 (デフォルトファイルが更新されるタイミングを正確に制御するには、msync(2)が必要です。)
別の方法で動作を修正するいくつかのLinux固有のマッピングフラグがあります。
- madvise(2) MADV_DONTFORK フラグで示されるメモリマップは、 fork() 全体から継承されません。
- madvise(2) MADV_WIPEONFORK フラグで示されるアドレス範囲のメモリは、 fork() 以降の子から消去されます。 (サブアドレス範囲の場合、MADV_WIPEONFORK設定は保持されます。)
存在するexec()
メモリイメージは新しいプロセスに置き換えられるため、継承されたメモリマップはすべてfork()
削除されます。
次の属性を除くすべてのプロセス属性はexecve()中に保持されます。
[...]
- メモリマッピング(mmap(2))は保持されません。
- 接続されたSystem V共有メモリセグメントが分離されました(shmat(2))。
- POSIX共有メモリ領域がマッピングされていません(shm_open(3))。