Linux/Unix C언어 데몬프로세스

백그라운드 수행/ fork() 실행.

fork 수행후, 부모로 부터 받은 File descriptor 를 close 한다.– 파일이 terminal 장치인경우, 데몬실행사용자가 로그아웃할때,   터미널 상태를 초기화 하려면 장치를 닫아야 한다.   열고 닫을수 있는 파일갯수의 최대값을 결정하려면, getrlimit () 호출한다.

프로세스는 프로세스 그룹을 변경한다. 프로세스 그룹은 시그널을 보내는데 사용한다. 터미널에서 같은 그룹에 속한 프로세스로 간주한다. 제어 터미널을 닫고, 세션그룹을 변경하는 것은,  데몬프로세스가 이전 그룹리더(shell) 로부터 의 잠재적인 시그널을 받는것을 막는다.

 프로세스는 세션에 속한 프로세스 그룹으로 구성되어 있다.  setsid () 시스템호출로 그 프로세스를 세션 리더로 하는 새로운 세션이 만들어지게 된다.데몬이 제어 터미널을 잃게 되면 다시 얻어서는 안된다.

프로세스 그룹리더가 새로운 터미널 장치를 열때 제어 터미널을 자동으로 얻는다.이를 막는 가장 쉬운 방법은 setsid() 호출 후 fork 를 다시 호출하는 것이다. 데몬은 두 번째 자식 프로세스로  실행하게 된다. 부모프로세스(세션과 프로세스 그룹리더)의 실행이 끝나면, 두번째 자식은 0 번의 새로운 프로세스 그룹을 얻게된다. (init의 자식프로세스가 되기때문이다)

따라서, 새로운 제어 터미널을 얻을 수는 없는데 이것은 프로세스 리더가 아니기때문이다.다양한 표준 라이브러리 루틴은 세가지 표준 입출력 디스크립터가 열려있다고 가정하기도 한다. 결과적으로 서버는 보통 세가지 모든 디스크립터를 열어두고 /dev/null 과 같이 시스템에 영향을 주지 않는 I/O 장치에 연결되어 있다.

데몬은 보통 부트할때 시작하고, 시스템이 가동하는 시간 동안 줄곧 실행중인상태로 떠있는다. 데몬이 마운트된 파일 시스템에서 시작하였다면 데몬을 죽이기 전까지 파일 시스템을 마운트를 해제 하는것이 불가능한다. 이를 고려하여 데몬 프로그래밍을 할때 chdir () 을 수행하여 / 로 놓는것이 현명하다

또는 , 데몬의 동작과 관계가 있는 파일이 파일 시스템으로 놓아도된다.데몬은, 부모 프로세스의 umask 정보를 물려 받는다.나중에 데몬에서 파일을 생성할때, 이를 방지하기 위해서는 보통 umask() 를 사용하여 0 으로 놓는다.

——————————————————–

리스트 1 예제코드에서 이러한 점을 설명한다.

세션을 지원하지 않는  시스템(리눅스,솔라리스 등)에서는 리스트2 코드를 사용하여 setsid() 와 같은 결과를 얻을 수 있다.

주서버코드에서 프로세스를 복제하여 만들어진 자식 프로세스가 종료하면할당된 메모리를 회수하지만, 프로세스 테이블의 엔트리에서는 제거되지 않는다. 프로세스가 죽게되면 예를 들어, 시스템자원을 소모하지는않지만, 그들을 완전히 되돌려받는것은 아니다, 그들이 좀비와 같은 형태가 되는 이유는 부모 프로세스가 필요한경우(PU 사용량등..) 자식 프로세스로부터 통계를 수집할 수 있도록 하기 때문이다.

분명히, 데몬은 프로세스 테이블이 좀비프로세스로 차는 것을 원치 않을 것이다.자식프로세스가 죽게되면 부모 프로세스에 SIGCHLD 시그널을 보낸다.부모가 자식을 강제로 회수하지 않는 한 시그널의 기본 핸들러가 자식을 좀비로 바꾼다.이는 리스트3 에서 볼수 있다. 대안으로 리스트4 에서 볼수 있듯이 시그널을 무시하고좀비가 죽도록 할 수도 있다.

데몬이 대부분의 다른 시그널을 무시하거나 SIGHUP 을 받은 후에 설정파일을 다시 읽고 재시작 하는 일도 자주 있다. 많은 데몬은 자식의 PID (프로세스번호)를 로그파일에 저장한다. 보통 /var/run/foobar.pid 가 되는데, 프로세스를 중단하는 경우 도움을 준다. 시스템을 셧다운 할때 (ㄷ또는 다중 사용자에서 단일 사용자 모드로 바뀔대) 모든 프로세스에게 알리기 위해 SIGTERM 시그널을 보낸다

그 다음 init 프로세스는 정해진 시간만큼 기다린다 (SVR4 에서는 2 초, BSD 에서는 5 초, 리눅스 init 에서는 5 sec, 리눅스셧다운에서는 기보값으로 3 초 이지만 명령행 인자에서 지정가능) 프로세스가 계속 살아 있으면 무시되지 않는 시그널인 SIGKILL 시그널을 보낸다.

 따라서 다른 프로세스가 정상적으로 종료하는지 확실히 하려면 데몬 프로세스가 SIGTERM 시그널을 가로챌수 있어야 한다.