p.124 ~ 143
fork()를 호출 하면 새로운 프로세스(자식 프로세스)가 생기는데, 자식 프로세스는 부모 프로세스의 PCB, 이미지 정보를 그대로 복사한다. PC도 복사하기 때문에 자식 프로세스도 부모 프로세스가 fork()한 시점부터 시작한다.
그러면 모든 정보가 부모와 똑같이 복사 하기 때문에 구분 하는데 어려움이 있다. 그래서 fork()의 return 값을 다르게 해서 구분한다. 부모에게는 0을 반환하고, 자식에게는 0이 아닌 수를 반환한다. 이 fork의 리턴 값으로 부모프로세스인지, 자식 프로세스인지 구분하여 각자 원하는 코드를 진행한다.
exec()를 호출 하면 현재 프로세스에 원하는 프로그램을 덮어쓴다. 그래서 exec()를 쓰면 현재의 프로세스에 완전히 새로운 프로그램으로 덮어 씌워지기 때문에 pid값은 바뀌지 않지만, 내부의 모든 코드, 데이터, 메모리가 새로운 프로그램으로 바뀐다.
유닉스나 리눅스에서는 프로세스의 생성이 fork와 exec 두가지로 나뉜다. fork는 부모와 똑같은 프로세스를 생성하고, exec는 현재 프로세스에 새로운 프로그램을 덮어씌운다.
wait()는 커널이 프로세스의 CPU를 뺏는다. 프로세스가 wait()을 호출하면, 커널모드의 트랩 핸들러에 진입하여 wait()을 실행하는데 이때 프로세스로 부터 CPU를 뺏는다(sleep 상태에 들어간다). 이 때 현재 프로세스의 정보를 PCB에 저장하고, ready queue list에서 준비된 프로세스 중 우선순위가 가장 높은 프로그램의 PCB를 찾고 PC를 알아낸 후 PC가 가리키는 쪽으로 가서 일을 수행한다. 이 것을 preemt라고한다.
main()문의 맨마지막에 exit()문이 없으면, 컴파일러가 마지막에 exit()문을 넣어서 컴파일해준다.
exit()호출 이후에 들어오는 시그널은 모두 무시하고, 열려있는 파일은 모두 닫아주고, 메모리는 모두 해제해주고 부모 프로세스에게 시그널을 통지하고 상태를 좀비상태로 설정한다.
<aside> 💡 좀비상태
자식 프로세스가 종료된 이후에 부모 프로세스가 자식 프로세스의 상태를 알아야 할때 자식 프로세스의 메모리는 이미 해제되었기 때문에 확인할수가 없다. 그래서 커널은 자식 프로세스가 종료되더라도 최소한의 정보(프로세스 ID, 프로세스 종료 상태 등)를 가지고 있게 된다. 부모 프로세스가 좀비 프로세스의 종료상태를 회수하게 되면(wait를 호출해서) 좀비 프로세스는 제거된다.
</aside>