fork ()와 vfork ()의 ​​차이점은 무엇입니까?


13

fork ()와 vfork ()의 ​​차이점을 자세하게 이해하고 싶습니다. 매뉴얼 페이지를 완전히 소화 할 수 없었습니다.

또한 동료 중 한 사람에게 " 현재 Linux에는 vfork ()가 없습니다. 전화를해도 내부적으로 fork ()를 호출 합니다."라고 말하고 싶습니다 .

답변:


24

매뉴얼 페이지는 일반적으로 간결한 참조 문서입니다. 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이것을 할 필요조차 없습니다. 대부분의 응용 프로그램에서 성능 향상은 무시할 수 있습니다.


1
이 훌륭한 답변에 감사드립니다. fork ()를하는 동안 아이는 어쨌든 새로운 프로세스 ID와 관련 가상 공간을 얻게되는데 왜 여전히 프로세스의 가상 메모리 테이블의 복사본을 만들어야합니까? 나는 그 부분이 명확하지 않습니다.
Sen

@Sen : 후속 COW ( forkCopy-On-Write) 사본이 두 프로세스 중 하나에 만 영향을 주도록 별도의 가상 메모리 맵핑을 작성해야합니다.
Gilles 'SO- 악의를 멈춰라'

부모 프로세스가 실행되고 있습니까?
qbolec

2

fork()vfork()콜은 다르다.

fork()콜은 별도의 메모리와 두 개의 동일한 프로세스를 생성한다. vfork()콜 동일한 메모리를 공유하는 두 개의 프로세스를 생성한다.

vfork()부모 와 함께 자녀의 종료를 기다립니다. 부모는 프로그램이 공유하는 변수에서 상속합니다. 따라서 자식이 호출 된 후에도 자식 내부에서 수정 된 모든 변수는 여전히 부모 내부에서 수정됩니다.

자세한 내용은 여기를 클릭 하십시오

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.