분기된 프로세스는 쓰기 시 매핑된 모든 메모리를 복사합니까?

분기된 프로세스는 쓰기 시 매핑된 모든 메모리를 복사합니까?

프로세스를 분기하면 상위 프로세스의 메모리가 매핑되고 쓰기 시 복사된다는 것을 알고 있습니다. 작성해야 하는 부분만 복사합니까, 아니면 매핑된 메모리 전체를 복사합니까?

답변1

짧은 답변: 어느 것도 아니다. 커널은 전체 페이지를 복사합니다. 페이지 크기는 사용 중인 아키텍처에 따라 다릅니다(현재 아키텍처는 여러 페이지 크기를 지원하는 경우가 많습니다). x86 64비트 아키텍처에서 실행 중인 경우 가장 가능성 있는 크기는 4KiB입니다.

더 긴 답변: 커널과 하드웨어 가상 메모리 시스템은 페이지라는 조각으로 메모리를 처리합니다. 예를 들어 x86 64비트 아키텍처의 기본 페이지 크기는 4KiB입니다.

이 기간 동안 fork()부모 메모리 공간의 대부분은 자식 프로세스와 공유됩니다. 이 메모리 공간은 페이지로 구성됩니다. 각 공유 페이지는 해당 기간 동안 커널에 의해 읽기 전용으로 표시됩니다 fork().

이후에 fork()완료누구나부모 또는 자식이 메모리 수정을 시도하고 페이지가 읽기 전용으로 표시되어 하드웨어에서 페이지 오류를 생성합니다. 페이지 오류는 커널에 갇히는 CPU 예외입니다(즉, 현재 프로그램 실행이 중지되고 CPU가 커널에서 미리 정의된 예외 처리기를 실행하기 시작합니다).

그런 다음 커널은 이것이 쓰기-복사 오류라고 판단하고 새 페이지를 할당합니다. 페이지가 읽기/쓰기로 표시되고 이전 페이지의 내용이 복사됩니다. 그런 다음 커널은 이를 메모리 공간에 매핑합니다. 그런 다음 캡처 명령에서 프로세스 실행이 재개됩니다. 즉, 오류를 유발한 명령이 다시 실행됩니다. 이번에는 페이지가 읽기/쓰기로 표시되어 명령이 오류 없이 완료됩니다.

이 프로세스는 자녀나 부모가 공유 페이지에 쓸 때마다 반복됩니다. 페이지에 CoW 오류가 발생한 후에도 일반적으로 "기타" 프로세스에서는 여전히 읽기 전용으로 표시됩니다(커널 구현에 따라 다름). 프로세스가 여기에 쓰기를 시도하면 이전과 같이 오류가 생성됩니다. 그러나 커널은 페이지가 더 이상 공유되지 않는다는 것을 알아차리고 단순히 읽기/쓰기로 표시합니다.

답변2

현대적인 구현은 1988년 SunOS-4.0과 함께 도입되었습니다 mmap(). 모든 최신 운영 체제는 SunOS-4.0에서 이 개념을 다시 구현합니다. 그 시점부터 fork()호출은 일반적으로 쓰기 중 복사 변형이었습니다.

상위 프로세스에서 공유 방식으로 매핑된 액세스 메모리에 쓰는 경우 해당 메모리는 하위 프로세스에서 공유된 상태로 유지됩니다. 액세스 개인 메모리에 쓰는 경우 이를 수정하려고 하면 개인 복사본으로 대체됩니다.

관련 정보