vfork 또는 포크의 자식이 exit () 대신 _exit ()를 호출해야하는 이유는 무엇입니까? 호출 할

의 맨 페이지에서 vfork():

vfork ()는 자식이 execve (2) 또는 _exit (2)를 호출 할 때까지 부모가 일시 중지된다는 점에서 fork ()와 다릅니다. 자식은 execve ()가 자식에 의해 발행 될 때까지 스택을 포함하여 부모와 모든 메모리를 공유합니다. 자식은 현재 함수에서 리턴하거나 exit ()를 호출해서는 안되지만 _exit ()를 호출 할 수 있습니다.

왜 아이 _exit()는 단순히 전화하기보다는 오히려 전화를 사용해야 exit()합니까? 이것이 vfork()와 에 모두 적용되기를 바랍니다 fork().



답변

으로 이전에 볼 , vfork자식 프로세스는 부모의 메모리에 액세스 할 수 없습니다. exitC 라이브러리 함수입니다 (그래서 종종로 작성 되는 이유 exit(3)). C 스트림 플러시 및 닫기 (에 선언 된 함수를 통해 파일이 열림 stdio.h) 및에 등록 된 사용자 지정 함수 실행 과 같은 다양한 정리 작업을 수행합니다 atexit. 이러한 모든 작업에는 프로세스 메모리를 읽고 쓰는 작업이 포함됩니다.

_exit정리하지 않고 종료합니다. 직접 시스템 호출 (이로 작성된 이유 _exit(2))이며 일반적으로 시스템 호출 번호를 프로세서 레지스터에 배치하고 특정 프로세서 명령어 (시스템 호출 핸들러로 분기)를 실행하여 구현됩니다. 프로세스 메모리에 액세스 할 필요가 없으므로 이후에 수행해도 안전합니다 vfork.

이후 fork에는 그러한 제한이 없습니다 : 부모와 자식 프로세스는 이제 완전히 자율적입니다.


답변

exitatexit복사 된 부품 외부의 데이터에 액세스 하여 등록 된 함수 호출과 같은 추가 정리를 수행 합니다. _exit커널 내를 제외한 모든 정리없이 직접 syscall을 수행합니다.


답변

자식 프로세스가 종료 될 때 stdio (또는 다른) 버퍼를 비우지 않도록 자식 호출 _exit ()가 있습니다. 자식 프로세스는 부모 프로세스의 정확한 복사본을 구성하기 때문에 자식 프로세스는 여전히 부모가 “stdout”또는 “stderr”에있는 <stdio.h>의 버퍼를 가지고 있습니다. 부모 프로세스의 버퍼가 가득 차고 플러시되면 exit ()를 호출하여 자식 프로세스의 atexit 핸들러에서 하나, 부모에서 하나를 호출하여 이중 출력을 얻을 수 있습니다.

위의 답변이 stdio.h 특정 사항에 집중한다는 것을 알고 있지만 위의 답변 중 하나가 나타내는 것처럼 다른 아이디어는 아마도 버퍼링 된 다른 I / O로 넘어갑니다.


답변

exit():-i / o 스트림을 닫는 것과 같은 많은 정리 작업을 수행 한 다음 커널로 돌아갑니다.
_exit():-커널에 직접옵니다 (정리 작업을 수행하지 마십시오).

fork() : 부모와 자식 모두 파일 테이블이 다르므로 자식에 의한 변경은 부모의 환경 매개 변수에 영향을 미치지 않으며 그 반대도 마찬가지입니다.

vfork(): 부모와 자식 모두 동일한 파일 테이블을 사용하므로 자식에 의한 변경은 부모의 환경 매개 변수에 영향을줍니다. 예를 들어 일부 변수 var=10는 이제 var++자식에 의해 실행 되고 부모를 실행하면 부모 var++의 출력에서도 영향을 볼 수 있습니다.

난 당신이 사용하는 경우 말했듯 exit()vfork()다음의 모든 I / O가 이미 닫혀 있습니다. 따라서 부모가 올바르게 실행 되더라도 모든 변수가 플러시되고 모든 스트림이 닫히므로 올바른 출력을 얻을 수 없습니다.