명령과 실행 환경 준비
셸은 인자, 파이프, 리다이렉션, 환경 변경을 정리한 뒤 외부 명령이면 자식 생성을 준비한다.
외부 명령 실행의 대표 경로는 부모가 자식을 만들고, 자식이 같은 PID에서 프로그램 이미지를 바꾸며, 부모가 wait로 결과를 읽어 커널 기록을 지우는 흐름이다.
셸은 인자, 파이프, 리다이렉션, 환경 변경을 정리한 뒤 외부 명령이면 자식 생성을 준비한다.
부모는 자식 PID를 받고, 자식은 0을 받는다. 실패하면 -1만 반환되고 자식은 만들어지지 않는다.
리다이렉션, close-on-exec, 환경 변수, 시그널 처리처럼 새 프로그램에 넘길 조건을 이 틈에서 조정한다.
성공하면 기존 코드로 돌아오지 않는다. PID는 유지되고 FD_CLOEXEC가 없는 파일 디스크립터는 이어진다.
부모는 먼저 waitpid로 블록될 수 있고, 자식 종료 뒤 반환되며 status를 읽고 좀비 기록을 제거한다.
코드와 스택은 사라졌지만 종료 status와 PID 항목이 남는다. 장기 서버는 SIGCHLD에서 waitpid(-1, ..., WNOHANG)를 반복한다.
현재 PID namespace의 init 또는 가장 가까운 subreaper가 입양한다. 컨테이너 PID 1은 reaping 책임을 피할 수 없다.
exec 성공은 반환하지 않는다. 다음 줄이 실행되면 실패 경로이므로 부모 로직을 다시 타지 않게 바로 종료한다.
fork 직후 물리 메모리 전체를 즉시 복사하는 것이 아니라, 쓰기가 발생한 페이지부터 실제 복사가 일어난다.
Ready, Running, Waiting 같은 CPU 스케줄링 모델과 달리 exec는 같은 프로세스 안의 프로그램 이미지 교체다.
종료 코드 확인과 함께 프로세스 테이블의 최소 기록을 제거하므로, 서버와 PID 1 역할 프로세스에서 필수다.