systemd process : 항상 pid값이 1이고, 모든 user process들의 root parent process이고, 시스템이 부팅된 이후로 처음으로 만들어지는 user process 이다. 부팅 이후에 systemd process가 여러 서비스를 제공하는 process들을 만든다.
init -> systemd로 바뀌었고, systemd가 더 유동적으로 사용될 수 있고, 더 많은 서비스도 만들 수 있다.
Process가 새로운 process를 만들 때, 실행상의 두 가지 경우가 존재한다.
address-space 상에서도 2가지 경우가 존재한다.
UNIX에서는 새로운 process는 fork() system call에 의해 만들어지고, 원래 프로세스의 주소공간의 복사본으로 구성된다. -> parent와 child의 소통을 쉽게 한다.(pipe같은 거 말하는듯)
fork() 이후에 둘 다 실행되는데, child의 경우 fork()의 리턴값이 0이고, parent의 경우 child의 pid값이 리턴된다.
fork() system call 이후에는 보통 둘 중 하나는 exec() system call을 사용하여 기존 exec() system call을 포함하고 있던 program의 memory image를 없애고 binary file을 momory에 load하여 실행시킨다. -> exec() 은 에러가 발생하기 전까지 control을 돌려주지 않는다.
parent가 child를 죽이는 이유들
몇몇 시스템에서는 부모가 종료된 이후에 자식이 존재하는 것을 허락하지 않는다. -> process가 terminate할 때, 그 process의 모든 자식 또한 terminate 시켜야 한다. -> cascading(계단식) termination -> 운영체제에 의해 보통 수행된다.
process가 terminate할 때, 그 process의 resource들은 운영체제에 의해 할당 해제된다. 하지만, process table에 그 process의 exit status가 남아있기 때문에, process table은 남게 된다.
process는 종료되었지만, parent가 wait()을 call 하지 않았을 때, 이를 zombie process라고 한다.
parent는 wait()을 호출하지 않았지만 child는 여전히 계속 실행되고 있는 상태에 대해서 child process를 orphan이라고 부른다. -> Traditional UNIX system은 orphan process들에 대해서 init process로 하여금 그들의 부모가 되도록 한다.
init process의 경우 주기적으로 wait()를 호출하기 때문에, orphaned process들은 정상적으로 할당 해제될 수 있다.
Linux 대부분은 init -> systemd로 바꾸었지만, systemd도 위 기능을 수행할 수 있다. 또한 systemd 말고도 다른 프로세스가 고아 프로세스를 상속해서 종료하는 것도 가능하다. (subreaper 말하는 듯.)