백그라운드 데몬프로세스 구현
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 |
댓글