매뉴얼 페이지에서 vfork()
:
vfork()는 자식 프로세스가 execve(2) 또는 _exit(2)를 호출할 때까지 부모 프로세스가 일시 중지된다는 점에서 fork()와 다릅니다. 하위 프로세스는 execve()를 실행할 때까지 스택을 포함하여 상위 프로세스와 모든 메모리를 공유합니다. 자식 프로세스는 현재 함수에서 반환하거나 exit()를 호출해서는 안 되지만 _exit()를 호출할 수는 있습니다.
_exit()
왜 아이들은 단순히 call 대신 an을 사용해야 합니까 exit()
? 이 기능이 vfork()
및 에서 작동하기를 바랍니다 fork()
.
답변1
~처럼일찍 만났어요, vfork
하위 프로세스가 상위 프로세스의 메모리에 액세스하는 것을 허용하지 않습니다.exit
C 라이브러리 함수입니다(그래서자주 쓴다처럼 exit(3)
). C 스트림 플러시 및 닫기( 에 선언된 함수를 통해 파일 열기 stdio.h
), 에 등록된 사용자 지정 함수 실행 등 다양한 정리 작업을 수행합니다 atexit
. 이러한 모든 작업에는 프로세스 메모리에 대한 읽기 및 쓰기가 포함됩니다.
_exit
정리하지 않고 종료합니다. 이는 직접적인 시스템 호출(그래서 작성되었습니다 _exit(2)
)이며 일반적으로 시스템 호출 번호를 프로세서 레지스터에 넣고 특정 프로세서 명령을 실행(시스템 호출 처리기로 분기)하여 구현됩니다. 이는 프로세스 메모리에 접근할 필요가 없으므로 나중에 실행해도 안전합니다 vfork
.
이후에는 fork
그러한 제한이 없습니다. 이제 상위 및 하위 프로세스가 완전히 자율적입니다.
답변2
exit
등록된 함수를 호출하여 atexit
복사된 부품 외부의 데이터에 액세스하는 등 추가 정리를 수행합니다. _exit
시스템 호출은 정리 없이 직접 실행됩니다(커널 내 제외).
답변3
하위 프로세스가 종료될 때 stdio(또는 기타) 버퍼를 플러시하는 것을 방지하기 위해 하위 프로세스 호출 _exit()가 있습니다. 하위 프로세스는 상위 프로세스의 정확한 복사본을 구성하므로 하위 프로세스는 여전히 상위 프로세스가 "stdout" 또는 "stderr"에 가지고 있던 모든 것, 즉 <stdio.h>의 버퍼를 갖습니다. 자식 프로세스의 atexit 처리기에서 하나, 부모 프로세스에서 하나(부모 프로세스의 버퍼가 가득 차서 플러시된 경우)를 호출하여 이중 출력을 얻을 수 있습니다(부적절한 경우).
위의 답변은 stdio.h의 세부 사항에 초점을 맞추고 있지만 위의 답변 중 하나에서 알 수 있듯이 아이디어는 다른 버퍼링된 I/O에도 적용될 수 있습니다.
답변4
exit()
:- i/o 스트림 닫기 등과 같은 일부 정리 작업을 수행한 다음 커널로 돌아갑니다.
_exit()
:- 정리 작업을 수행하지 않고 커널로 직접 이동합니다.
fork()
: 부모와 자식 모두 서로 다른 파일 테이블을 가지므로 자식이 변경한 사항은 부모의 환경 매개변수에 영향을 주지 않으며 그 반대의 경우도 마찬가지입니다.
vfork()
: 상위 프로세스와 하위 프로세스는 동일한 파일 테이블을 사용하므로 하위 프로세스의 변경 사항은 상위 프로세스의 환경 매개변수에 영향을 줍니다. 예를 들어, 이제 하위 프로세스에 의해 변수가 var=10
실행되고 상위 프로세스가 실행되는 경우 상위 프로세스의 출력에서도 그 효과를 볼 수 있습니다 var++
.var++
내가 말했듯이 exit()
in을 사용하면 vfork()
모든 I/O가 이미 닫혀 있습니다. 따라서 상위 프로세스가 올바르게 실행되더라도 모든 변수가 플러시되고 모든 스트림이 닫히기 때문에 올바른 출력을 얻을 수 없습니다.