본문 바로가기
소프트웨어개발

C 데몬프로세스 만들기

by 보이드메인 2020. 10. 16.

백그라운드 데몬프로세스 구현

C 코드 서버 프로그램은, 대개 백그라운도로 동작하며, 이를 위해 백그라운드 Daemonize 기능을 구현해야 한다.

여러가지 방식이 있지만, 대강 구현 방식은 이렇다.

 

1. 총 2회의 fork()를 수행한다.

main 함수가 호출되는 초기에 첫 fork() 수행하여, parent process 는 exit() 함과 동시에,

Child Process 에게 session 권한을 부여한다.

 

session 권한으로 주인이 된 child Process 는 두번째 fork()를 수행하고, Parent process 는 exit() 하고,

무한 loop 작업을 Child Process 에게 맡긴다. 

 

마지막 Child Process 가 데몬의 주인이 된다.

 

2. 시그널 차단 작업

백그라운드에서 실행되는 프로그램이므로

터미널의 이벤트 와 OS의 각종 시그널을 차단 또는 처리하는 코드를 넣어주면 된다.

 

3. OS 가 선점한 fd close 작업

표준출력stdout(1)/표준에러stderr(2)/표준입력stdin(0)  OS 가 선점한 할당된 fd 값을 close() 한다.

 

아래 코드를 보자

 #include <sys/types.h>

#include <sys/stat.h>

#include <stdio.h>

#include <fcntl.h>

int main()

{

pid_t   pid;

 

// 첫번째 fork 를 실행한다.

if (( pid = fork()) < 0) return -1;

else if ( pid != 0) exit(0);   // child 생성후 parent 종료, 백그라운드 실행시점. child 만 이하를 실행한다. 

 

/* 세션 권한을 부여한다. 

fork 로 생성된 child process 를 현재세션과 무관하게 동작하도록 한다.

새로운 하나의 세션을 만들고, 세션리더가 된다. 새로운 세션을 그룹을 만들고 그룹의 리더가된다.

setsid 를 호출하여 만든 세션은 제어터미널을 가지고 있지 않다.

이미 프로세스의 그룹리더인 프로세스는 호출할 수 없다.

*/

// fork 로 생성된 child process 를 현재세션과 무관하게 동작하도록 한다.

setsid();

 

// SIGHUP 시그널을 무시한다.

// 데몬프로세스는 터미널과 연결되지 않으므로,

// SIGHUP 시그널을 수신하더라도 중지하지 않아야한다.

signal(SIGHUP, SIG_IGN);

 

  // 두번째 fork 를 실행한다. 자식 프로세스를 만든다.

  if ((pid = fork()) != 0)

  exit(0);   / * 부모 프로세스는 종료 시킨다. */

  chdir("/"); /* 디렉토리 변경 */

 

// 데몬프로세스는 표준출력stdout(1)/표준에러stderr(2)/표준입력stdin(0)이 없으므로,

//  관련fd 를 닫는다.

  for (fd = 0; fd < 3; fd++)

             close(fd);

 

 umask(0);

      

// 데몬 프로그램이 실행할 코드를 작성한다.

 while(1)

 {

  // ---  forever ---

 }  

} // end of main()


보통 아래와 같이 한다.

 

if ((pid = fork()) != 0)

exit(0); 

setsid();

 

signal(SIGHUP, SIG_IGN); /* SIGHUP 시그널을 무시한다. */

 

if ((pid = fork()) != 0) 

exit(0); / * 부모 프로세스는 종료 시킨다. */

chdir("/"); /* 디렉토리 변경 */

umask(0);

 

for (i = 0; i < MAXFD; i++)

close(i); /* 혹시 모르는 열려진 fd 를 닫는다. */

 

// 데몬 

int daemon_init(void)

{

     pid_t    pid;

     int    fd;

     if ((pid = fork()) < 0)    return (-1);

     else if (pid != 0)            exit(0);

     setsid();

     chdir("/");

     fd = open ("dev/null", O_RDWR);

     dup2(fd, 1);

     dup2(fd, 2);

     dup2(fd, 0);

     close(fd);

     umask(0);

     return(0);

}

'소프트웨어개발' 카테고리의 다른 글

C 언어 cat 명령구현  (0) 2020.12.16
Java Daemon 백그라운드 프로세스 구현  (0) 2020.10.23
opensource VoIP,IP-PBX : asterisk  (0) 2020.06.02
C, File I/O, open(), fopen() 그리고 dup()  (0) 2020.03.30
select,epoll,poll  (0) 2020.03.18

댓글