fork exec

fork/exec 두 단계

fork는 현재 프로세스 문맥을 자식으로 복제하고, exec는 그 자식의 주소 공간을 새 프로그램으로 바꾼다. shell 실행 모델은 이 조합으로 설명된다.

01

프로세스를 복제한다

fork 뒤 부모와 자식은 반환값으로 서로를 구분하고 각자 실행을 계속한다.

02

필요한 descriptor를 정리한다

exec 전 자식은 stdin/stdout 리다이렉션과 불필요한 파일 descriptor close를 처리한다.

03

이미지를 교체한다

exec 성공 뒤에는 이전 코드로 돌아오지 않고 새 프로그램의 entry point가 실행된다.

Return
분기 기준 부모는 자식 pid, 자식은 0, 실패는 -1을 받는다.
여기서 흐름이 둘로 갈린다.
COW
복사 비용 지연 부모와 자식이 같은 페이지를 공유하다가 쓰기 시점에 복사한다.
fork 비용을 줄인다.
Exec
프로그램 교체 코드, data, heap, stack이 새 실행 파일 기준으로 바뀐다.
pid는 유지된다.
Zombie
종료 상태 미회수 부모가 wait하지 않으면 종료 정보가 process table에 남는다.
wait/waitpid가 필요하다.

분기 · descriptor · 회수 점검

분기 fork 반환값별 부모/자식 실행 경로가 명확한가.
descriptor pipe와 redirect에서 쓰지 않는 FD를 부모와 자식이 닫는가.
회수 자식 종료 뒤 wait로 zombie를 남기지 않는가.

shell 흐름

fork() -> child: dup2()/close() -> execve()
        parent: close unused fd -> waitpid()