Daemon 프로그램은 보통 telnet, httpd, mysql 과 같은 각종 서버를 background 상태에서 돌아가는 프로그램을 말한다. 그러나 background 프로그램과 Daemon 프로그램은 엄연한 차이가 있다.
일반적인 background 프로그램은 터미널을 가지지만, Daemon 프로그램은 터미널을 가지지 않는다.
왜냐하면 보통 데몬프로그램은 특별한 일이 없는한 사용자와 상호대화할 필요 없이 아무도 모르게 실행되어야 하기 때문이다.
또한 모든 데몬 프로그램은 PPID 즉 부모 프로세스가 1번으로 세팅되며, 이는 데몬 프로그램의 관리프로세스는 1번 pid 를 가지는 init 가 담당함을 의미한다.
위의 화면은 my_server 란 프로그램을 백그라운드 모드로 실행시켰을 경우와 -D 옵션을 줘서 데몬모드로 실행시켰을때의 ps 정보를 보여준다.
데몬 프로세스의 경우를 보면 알겠지만, PPID가 1로 세팅되어 있으며 TTY 즉 터미널을 가지지 않음을 알수 있다. 그래고 SID 역시 자신의 PID와 같다는것을 알수 있다.
그럼 이제 실질적으로 데몬 프로그램을 만들도록 해보자, 데몬 프로그램을 만드는 핵심은 바로위에서 설명한대로 터미널을 가지지 않으며 PPID가 1인 프로세스를 만드는 것으로 아래와 같은 코딩 규칙을 이용해서 작성가능하다.
1. 우선 fork 를 호출해서 자식프로세스를 생성시킨 다음 부모프로세스를 종료시킨다.
2. setsid 를 이용하여 새로운 세션을 만들고, 현재프로세스(자식)의 PID가 세션의 제어권을 가지도록 한다.
3. chdir 을 이용하여 프로세스가 루트디렉토리에서 작업을 수행하도록 변경시켜준다.
1번을 이해하려면 fork에 대한 이해가 필요한데, 기본적으로 부모프로세스가 자식프로세스를 fork 했을경우 해당 자식프로세스의 PPID 는 부모프로세스의 ID 가된다. 그런데 자식이 죽기전에 부모프로세스가 죽어버리면 자식프로세스의 PPID 는 (다시말해서 자식프로세스의 소유 프로세스) 누가될까 ?
부모 프로세스는 이미 죽었음으로 PPID가 될수 없을것이다.
이럴 경우 자동적으로 자식프로세스의 관리 프로세스는 PID 1 번인 init 가 담당하게 된다.
2번의 setsid 는 새로운 새션을 생성하기 위해서 사용한다. 보통 세션은 자신의 세션을 위한 tty 를 가져야 되는데, 새로운 세션을 생성하면 여기에 tty 를 부여해 주어야 한다. 그렇지 않게 될경우 터미널을 가지지 않은 세션이 생성되게 된다. 세션(Session)에 대한 논의는 다른 문서를 참고하기 바라고, 간단히 생각해서 세션이란 프로그램 그룹의 모음이라고 일단은 생각해주길 바란다.
어쨋든 이렇게 해서 프로세스는 자신만의 독자적인 길을 걷게 된다.
3번은 선택사항이다. 굳이 해주지 않아도 되지만, 데몬 프로그램에서 여러가지 파일을 읽고 쓰는 작업을 할때 상대경로를 명시함으로써 일어나는 혼동을 피하기 위해서 권장하는 방법이라고 생각하면 될것이다.
데몬프로세스의 위의 3가지 조건만 만족시켜주면 된다. 그럼 에제를 통해서 실제 데몬 프로그램을 만들어서 실행시키고, 그 결과를 확인해 보도록 하자.
예제 daemon.c
아주아주 간단하게 데몬프로그램을 만들수 있음을 알수 있다.
이제 결과를 한번 확인해 보도록 하자
PPID가 1로 되어 있고 SID가 자신의 PID로 되어있으며 tty 를 가지지 않은 프로세스가 만들어졌음을 알수 있을것이다.
모든 프로그램에 위의 코드만 추가시켜주면 어렵지 않게 데몬프로그램을 제작할수 있을것이다.
일반적인 background 프로그램은 터미널을 가지지만, Daemon 프로그램은 터미널을 가지지 않는다.
왜냐하면 보통 데몬프로그램은 특별한 일이 없는한 사용자와 상호대화할 필요 없이 아무도 모르게 실행되어야 하기 때문이다.
또한 모든 데몬 프로그램은 PPID 즉 부모 프로세스가 1번으로 세팅되며, 이는 데몬 프로그램의 관리프로세스는 1번 pid 를 가지는 init 가 담당함을 의미한다.
[yundream@huhu loging_server]$ ./my_server&[yundream@huhu loging_server]$ ps -efjcUID PID PPID PGID SID CLS PRI STIME TTY TIME CMDyundream 4314 4219 4314 4175 - 30 15:36 ttyp0 00:00:00 ./my_server&[yundream@huhu loging_server]$ ./my_server -D[yundream@huhu loging_server]$ ps -efjcUID PID PPID PGID SID CLS PRI STIME TTY TIME CMDyundream 4319 1 4319 4319 - 30 15:37 ? 00:00:00 ./my_server |
데몬 프로세스의 경우를 보면 알겠지만, PPID가 1로 세팅되어 있으며 TTY 즉 터미널을 가지지 않음을 알수 있다. 그래고 SID 역시 자신의 PID와 같다는것을 알수 있다.
그럼 이제 실질적으로 데몬 프로그램을 만들도록 해보자, 데몬 프로그램을 만드는 핵심은 바로위에서 설명한대로 터미널을 가지지 않으며 PPID가 1인 프로세스를 만드는 것으로 아래와 같은 코딩 규칙을 이용해서 작성가능하다.
1. 우선 fork 를 호출해서 자식프로세스를 생성시킨 다음 부모프로세스를 종료시킨다.
2. setsid 를 이용하여 새로운 세션을 만들고, 현재프로세스(자식)의 PID가 세션의 제어권을 가지도록 한다.
3. chdir 을 이용하여 프로세스가 루트디렉토리에서 작업을 수행하도록 변경시켜준다.
1번을 이해하려면 fork에 대한 이해가 필요한데, 기본적으로 부모프로세스가 자식프로세스를 fork 했을경우 해당 자식프로세스의 PPID 는 부모프로세스의 ID 가된다. 그런데 자식이 죽기전에 부모프로세스가 죽어버리면 자식프로세스의 PPID 는 (다시말해서 자식프로세스의 소유 프로세스) 누가될까 ?
부모 프로세스는 이미 죽었음으로 PPID가 될수 없을것이다.
이럴 경우 자동적으로 자식프로세스의 관리 프로세스는 PID 1 번인 init 가 담당하게 된다.
2번의 setsid 는 새로운 새션을 생성하기 위해서 사용한다. 보통 세션은 자신의 세션을 위한 tty 를 가져야 되는데, 새로운 세션을 생성하면 여기에 tty 를 부여해 주어야 한다. 그렇지 않게 될경우 터미널을 가지지 않은 세션이 생성되게 된다. 세션(Session)에 대한 논의는 다른 문서를 참고하기 바라고, 간단히 생각해서 세션이란 프로그램 그룹의 모음이라고 일단은 생각해주길 바란다.
어쨋든 이렇게 해서 프로세스는 자신만의 독자적인 길을 걷게 된다.
3번은 선택사항이다. 굳이 해주지 않아도 되지만, 데몬 프로그램에서 여러가지 파일을 읽고 쓰는 작업을 할때 상대경로를 명시함으로써 일어나는 혼동을 피하기 위해서 권장하는 방법이라고 생각하면 될것이다.
데몬프로세스의 위의 3가지 조건만 만족시켜주면 된다. 그럼 에제를 통해서 실제 데몬 프로그램을 만들어서 실행시키고, 그 결과를 확인해 보도록 하자.
예제 daemon.c
#include <sys/types.h> #include <sys/stat.h> #include <stdio.h> #include <fcntl.h> int main(){ pid_t pid; if (( pid = fork()) < 0) exit(0); // 부모프로세스를 종료한다. else if(pid != 0) exit(0); //setsid(); chdir("/"); // 여기에 프로그램 본체를 넣는다. setsid(); while(1) { sleep(1); }} |
이제 결과를 한번 확인해 보도록 하자
[yundream@localhost test]$ ./daemon[yundream@localhost test]$ ps -efjc | grep daemonUID PID PPID PGID SID CLS PRI STIME TTY TIME CMDyundream 18710 1 18710 18710 - 30 23:42 ? 00:00:00 ./daemon |
모든 프로그램에 위의 코드만 추가시켜주면 어렵지 않게 데몬프로그램을 제작할수 있을것이다.
'UNIX_LINUX_C_C++' 카테고리의 다른 글
IPC 설비-메시지 큐 (0) | 2011.10.16 |
---|---|
polling 개념잡기 - Polling Made Efficient (select vs poll vs /dev/poll) (0) | 2011.10.16 |
Solaris 등등 컴터문서 링크 (0) | 2011.10.16 |
Network 프로그래밍 (0) | 2011.10.16 |
[joinc] 함수포인터의 사용 (0) | 2011.10.16 |