답변:
매뉴얼 페이지는 일반적으로 간결한 참조 문서입니다. Wikipedia 는 개념적 설명을하기에 더 좋은 곳입니다.
Fork는 프로세스를 복제합니다. 프로세스는 부모 프로세스와 거의 동일한 자식 프로세스를 만듭니다 (가장 큰 차이점은 새 프로세스의 프로세스 ID가 다르다는 것입니다). 특히, 포크는 개념적으로 모든 상위 프로세스의 메모리를 복사해야합니다.
vfork는 비용이 많이 들기 때문에 사본이 필요하지 않은 일반적인 특수한 경우를 처리하기 위해 발명되었습니다. 자식 프로세스에서 가장 먼저하는 일은 새로운 프로그램 이미지를로드하는 것입니다.
if (fork()) {
# parent process …
} else {
# child process (with a new copy of the process memory)
execve("/bin/sh", …); # discard the process memory
}
이 execve
호출은 새로운 실행 가능 프로그램을로드하며, 이는 프로세스의 코드와 데이터 메모리를 새로운 실행 가능 코드와 새로운 데이터 메모리로 대체합니다. 그래서 전체 메모리 사본 fork
은 아무것도 아닙니다.
따라서 vfork
전화가 발명되었습니다. 메모리 사본을 만들지 않습니다. 따라서 vfork
저렴하지만 하위 프로세스에서 프로세스의 스택 또는 힙 공간에 액세스하지 않아야하기 때문에 사용하기가 어렵습니다. 부모 프로세스가 계속 실행되기 때문에 읽기조차도 문제가 될 수 있습니다. 예를 들어,이 코드가 손상되었습니다 (자식 또는 부모가 먼저 타임 슬라이스를 가져 오는지 여부에 따라 작동하지 않을 수 있음).
if (vfork()) {
# parent process
cmd = NULL; # modify the only copy of cmd
} else {
# child process
execve("/bin/sh", "sh", "-c", cmd, (char*)NULL); # read the only copy of cmd
}
vfork가 발명 된 이후, 더 나은 최적화가 발명되었습니다. Linux를 포함한 대부분의 최신 시스템은 COW ( Copy-On-Write) 형식을 사용하는데 , 여기서 fork
호출 시 프로세스 메모리의 페이지가 복사되지 않고 나중에 부모 나 자식이 페이지에 쓸 때 복사됩니다 . 즉, 각 페이지는 공유 된 것으로 시작하여 프로세스가 해당 페이지에 쓸 때까지 공유 상태를 유지합니다. 쓰는 프로세스는 동일한 가상 주소를 가진 새로운 물리적 페이지를 얻습니다. Copy-on-Write는 vfork를 쓸모 없게 만듭니다 . 사용 가능한 fork
경우에는 사본을 만들지 않기 때문 입니다 vfork
.
리눅스는 vfork를 유지합니다. fork
시스템 콜은 여전히 실제 메모리를 복사하지 않는 경우에도, 프로세스의 가상 메모리 테이블의 복사본을해야합니다; vfork
이것을 할 필요조차 없습니다. 대부분의 응용 프로그램에서 성능 향상은 무시할 수 있습니다.
fork
Copy-On-Write) 사본이 두 프로세스 중 하나에 만 영향을 주도록 별도의 가상 메모리 맵핑을 작성해야합니다.