공유 메모리를 생성하기 위해 mmap()을 사용한다고 가정해 보겠습니다. 총 메모리 크기가 4096이라고 가정합니다. 자식 프로세스를 생성하기 위해 fork() 시스템 호출을 사용하는 경우, 자식 프로세스는 동일한 메모리를 사용합니까, 아니면 작동하려면 자체 메모리가 있어야 합니까?
답변1
존재하다fork()
상위 프로세스의 메모리 공간이 하위 프로세스에 복제됩니다. 최적화로서 최신 운영 체제는 COW(기록 중 복사)를 사용하므로 하위 프로세스 중 하나가 변경을 수행할 때까지 모든 개인 메모리가 하위 프로세스와 공유됩니다. 그런 다음 영향을 받은 메모리 페이지가 복사됩니다.
하위 프로세스와 상위 프로세스는 서로 다른 메모리 공간에서 실행됩니다. 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)).