Recommanded Free YOUTUBE Lecture: <% selectedImage[1] %>

Daemon 프로세스

Daemon 프로그램은 telnet, httpd, mysql, sshd 와 같이 background 상태에서 장시간 돌아가는 프로그램을 말한다. 하지만 백그라운드 프로세스와 데몬(Daemon) 프로세스는 분명한 차이가 있다.

일반적인 background 프로그램은 터미널을 가지지만, Daemon 프로그램은 터미널을 가지지 않는다. 왜냐하면 보통 데몬프로그램은 특별한 일이 없는한 사용자와 상호대화할 필요 없이 아무도 모르게 실행되어야 하기 때문이다.

또한 모든 데몬 프로세스는 PPID 즉 부모 프로세스가 1번으로 세팅된다. 이는 데몬 프로세스는 다른 어떤 프로세스의 영향도 받지 않음을 의미한다.

vim을 background로 실행하고, 내가 만든 데몬 프로그램을 실행해봤다.
$ vim & 
[1] 25825
[1]  + 25825 suspended (tty output)  vim                                        
$ ps -efjc
UID        PID  PPID  PGID   SID   CLS PRI STIME TTY          TIME CMD
yundream 25825 24792 25825 24792   TS   14 14:21 pts/3    00:00:00 vim

$ ./my_server -D
$ ps -efjc
UID        PID  PPID  PGID   SID   CLS PRI STIME TTY          TIME CMD
yundream  4319     1  4319  4319     -  30 15:37 ?        00:00:00 ./my_server
vim의 PPID(부모프로세스 아이디)는 24792 이다. PPID 27492가 뭐하는 프로세스인지 확인해보자.
# ps -ef | grep 24792
UID        PID  PPID  C STIME TTY          TIME CMD
yundream 24792  3280  0 14:07 pts/3    00:00:00 /usr/bin/zsh
yundream 25825 24792  0 14:21 pts/3    00:00:00 vim
쉘(zsh) 프로세스라는 걸 알 수 있다. 결국 vim은 zsh에서 실행한 프로세스라는 의미가 되겠다. vim은 zsh의 자식 프로세스이므로 zsh의 상태에 영향을 받는다. 대표적으로 zsh 프로세스가 종료되면 SIGTERM 시그널은 vim(기타 모든 자식 프로세스에 전달된다.)에 전달되고, vim도 함께 종료된다.

데몬 프로세스 my_server를 보면 PPID가 1인 것을 확인 할 수 있다. 따라서 운영체제가 종료되기 전까지는 계속 살아있게 된다.

그럼 데몬 프로세스를 만드는 방법을 살펴보자. 데몬 프로세스의 핵심은
  1. 터미널을 가지지 않으며
  2. PPID가 1인 프로세스를 만드는 것
에 있다. 이런 프로그램은 아래의 규칙을 이용해서 만들 수 있다.
  1. fork 함수를 호출해서 자식프로세스를 만든다.
  2. 부모 프로세스를 종료한다.
  3. setsid를 이용해서 새로운 세션을 만들어서, 현재 프로세스(자식 프로세스)의 PID가 세션의 제어권을 가지게 한다.
  4. chdir을 이용해서 프로세스의 작업디렉토리를 변경한다.
부모프로세스가 fork로 자식프로세스를 만들면, 자식 프로세스의 PPID는 부모프로세스의 PID가 된다. 이 상황에서 부모프로세스가 죽어버리면, 자식프로세스는 고아 프로세스가 된다. 부모프로세스가 사라졌으니 PPID는 사용 할 수 없게되고, PID 1번인 init 프로세스가 PPID가 된다.

setsid는 새로운 세션을 만들기 위해서 사용한다. 세션은 자신의 세션을 위한 tty를 가져야 하는데, 새로운 세션을 생상하면 여기에 tty를 부여해 줘야 한다. 그렇지 않을 경우 터미널을 가지지 않은 세션이 만들어진다. 이렇게 해서 PPID가 1이고 터미널을 가지지 않은 프로세스가 만들어졌다.

5번은 선택사항이다. 데몬 프로세스의 생성에는 관여하지 않지만, 데몬 프로세스가 작업할 디렉토리를 명확히 해주는게 좋을 것이다. 권장사항 같은거라고 보면 되겠다.

이제 실제 데몬 프로그램을 만들어서 테스트를 해보자. 실행하고 결과를 확인해보자.
$ ./daemon
$ ps -efjc | grep daemon
UID         PID  PPID  PGID   SID   CLS PRI STIME TTY          TIME CMD
yundream 26987       1 26987 26987 TS   19 14:48 ?        00:00:00 ./daemon
PPID가 1이고, SID가 자신의 PID 이며, tty를 가지지 않은 프로세스가 만들어졌다.