fork()
시스템 호출은 실행중인 프로세스에서 자식 프로세스를 복제합니다. PID를 제외하고 두 프로세스는 동일합니다.
당연히 프로세스가 쓰지 않고 힙에서 읽는 경우 힙을 복사하면 메모리가 많이 낭비됩니다.
전체 프로세스 힙이 복사됩니까? 쓰기 만 힙 복사를 트리거하는 방식으로 최적화 되었습니까?
fork()
시스템 호출은 실행중인 프로세스에서 자식 프로세스를 복제합니다. PID를 제외하고 두 프로세스는 동일합니다.
당연히 프로세스가 쓰지 않고 힙에서 읽는 경우 힙을 복사하면 메모리가 많이 낭비됩니다.
전체 프로세스 힙이 복사됩니까? 쓰기 만 힙 복사를 트리거하는 방식으로 최적화 되었습니까?
답변:
전체 의 fork()
mmap를 사용하여 구현됩니다 / 쓰기에 복사합니다.
이는 힙뿐만 아니라 공유 라이브러리, 스택, BSS 영역에도 영향을줍니다.
우연히도 결과 2 프로세스 (부모 및 자식)가 실제로 메모리 범위에 쓰기를 시작할 때까지 포크가 매우 가벼운 작업임을 의미합니다. 이 기능은 포크 폭탄의 치명적인 원인이됩니다. 페이지 복제 및 차별화로 커널이 오버로드되기 전에 너무 많은 프로세스가 필요합니다.
현대 OS에서 커널이 하드 카피를 수행하는 작업의 예 (장치 드라이버는 예외 임)를 찾기가 쉽지 않을 것입니다. VM 기능을 사용하는 것이 훨씬 쉽고 훨씬 효율적입니다.
심지어 execve()
"이진 / ld.so / whatnot,이어서 실행"을 수행하십시오. VM은 프로세스를 RAM 및 실행에 실제로로드하는 것을 처리합니다. 초기화되지 않은 로컬 변수는 '제로 페이지'에서 mmaped-0을 포함하는 특수한 읽기 전용 copy-on-write 페이지, 로컬 초기화 된 변수는 이진 파일 자체에서 mmaped (write-on-write, 다시) 기타
Linux 커널 fork()
은 호출 시 복사시 쓰기를 구현 합니다. syscall이 실행될 때 부모와 자식이 공유하는 페이지는 읽기 전용으로 표시됩니다.
읽기 전용 페이지에서 쓰기가 수행되면 두 프로세스간에 메모리가 더 이상 동일하지 않으므로 복사됩니다. 따라서 읽기 작업 만 수행중인 경우 페이지가 전혀 복사되지 않습니다.
fork()
호출 후 다음 명령이 아닌 시작부터 실행되는 동일한 프로그램의 인스턴스를 더 많이 생성하는 것으로 보입니다 .
/proc/self/pagemap
하여 시험의 목적의 물리적 페이지 매핑 가상 주소를 확인합니다. 예상대로, 손자와 손자 만 공유 페이지를 작성하면 부모와 원래의 자식은 계속 공유합니다. 손자 만 개인 사본으로 끝납니다.