데몬처럼 동작하는 프로그램을 만들려면???
글쓴이: ero / 작성시간: 금, 2006/01/13 - 4:31오전
#include<stdio.h> #include<unistd.h> #include<fcntl.h> #define SIZE 1024 #define LOGFILE "/var/log/secure" int main(int argc,char *argv[]) { int fd,i; unsigned long int filesize1=0,filesize2=0; char buf[SIZE]; int a; if((fd=open(LOGFILE,O_RDONLY))==-1) { perror("LOGFILE error"); exit(1); } while((i=read(fd,buf,SIZE))>0) filesize1+=i; filesize1=lseek(fd,0,SEEK_END); i=0; while(1) { filesize2=lseek(fd,0,SEEK_END); if(filesize1!=filesize2) { printf("\n-----------------------------------------------------------------------------------\n\a"); i=filesize2-filesize1; lseek(fd,-i,SEEK_END); i=read(fd,buf,SIZE); write(STDOUT_FILENO,buf,i); filesize1=filesize2; } filesize2=0; i=0; sleep(5); } close(fd); return 0; }
아주 간단하게 만든 로그 모니터하는 프로그램인데
데몬처럼 동작하게 할려면 어떻게 해야 되는건가여?
fork()함수를 쓰면 될까요??
아니면 다른 방법이 있는건가요??
Forums:
대몬을 만드시려면..
fork() 하시면 됩니다.
리턴되는 pid 검사해서 parent 이면 exit() 하시고요.
파일 다루시려면, umask(0) 정도 해주시는게 좋겠죠.
그럼
vio:
[code:1]void startDaemon()
참고하세요.
----------------------------------------------
한번뿐인 인생....
미친듯이 살아보자!
----------------------------------------------
[quote="kuaaan"][code:1]void startDaemon
혹시 모르니 윗분이 쓰신대로
umask(0)과 chdir("/') 도 해주세요.
보시다시피 저게 무한루프입니다.그래서 실행시킬때 백그라운드로 실행을
보시다시피 저게 무한루프입니다.
그래서 실행시킬때 백그라운드로 실행을 시키거든요..
그럼 데몬으로 만들어도 백그라운드로 실행 시켜야 되는건가요??
그리고 궁금한게 생겼습니다.
데몬으로 프로그래밍해서 실행시키는 거랑
/etc/rc.d/rc.local안에
'프로그램' &
이렇게 부팅시 백그라운드에서 동작하게 하는거랑
무슨 차이가 있는거죠??
[quote="yisuyong"]보시다시피 저게 무한루프입니다.그래서
백그라운드로 돌릴 경우에는 프로세스가 제어터미널을 가지고 있습니다. 예를들어 리모트 접속을 한 상태(현재 터미널은 pts/0)에서 프로그램을 백그라운도 돌리면 해당 프로그램은 제어터미널로 pts/0을 가지고 있습니다. 입출력이 pts/0을 통해서 이루어지죠. ps -ef를 해서 확인해보면 프로세스가 어떤 터미널상에 있는지 볼 수 있습니다.
그리고 중요한점이 pts/0이 닫히면 프로그램도 같이 죽습니다. 안죽게 하는 방법도 있지만 기본적으로 그렇습니다. 하지만 데몬화를 시키면 제어터미널이 없어지기 때문에 따로 kill signal을 보내지 않는 이상은 죽지 않습니다. 또한 데몬은 터미널이 없기 때문에 입출력을 따로 로그 파일을 만든다던지 아니면 콘솔에 쓴다던지 하게 됩니다. ps -ef로 볼때 데몬은 터미널이 없기 때문에 ?로 나옵니다.
그리고 저 프로그램을 데몬화 시키면 따로 백그라운도 실행하실 필요 없습니다. 데몬화 된 프로그램은 실행시키면 바로 프롬프트로 돌아옵니다.
더 자세한 답변은 다른 고수님께~
======================
BLOG : http://superkkt.com
[quote="superkkt"]그리고 중요한점이 pts/0이 닫
저도 데모나이즈하는 이유가 기본적으로
터미널이 닫히면 프로그램이 죽는다고 들어서 그런가 보다
생각했었습니다.
그런데 관련 자료를 찾아봤지만(APUE, Unix Network Programming) 그런 이야기를 쓰지 않고
다만 부모로부터 물려받은 디스크립터에 접근시 holding될 수
있기때문에라는 잘 이해가 되지않은 말로 쓰여있습니다.
이 이야기에 대해서 좀더 알 수 있을까요?
C++, 그리고 C++....
죽어도 C++
{{{int daemon(int nochdir, int noclose
{{{
int daemon(int nochdir, int noclose);
}}}
을 사용하실 수도 있습니다.
[quote="Anonymous"]{{{int daemon(int n
와 이런것도 있었군요.
감사.
아래처럼하니. 되네요.
JOINC 참고 소스
kill -TERM
으로 죽이면 뒷처리등도 가능하겠군요.
고작 블로킹 하나, 고작 25점 중에 1점, 고작 부활동
"만약 그 순간이 온다면 그때가 네가 배구에 빠지는 순간이야"
[quote="ixevexi"][quote="superkkt"]그
몇 페이지에 그런 내용이 있나요?
======================
BLOG : http://superkkt.com
[quote="superkkt"][quote="yisuyong"]보시다시
그런데 제가 말 했듯이 /etc/rc.d/rc.local 스크립트에
'프로그램' &
백그라운드로 실행하게 추가 한다음 리부팅해서
ps -ef 하면 부모프로세스가 init데몬으로 나옵니다.
그리고 pts/0가 닫혀도 여전히 실행이 되던데요?
잘은 모르지만 쉘이 떨어지기 전에 실행되는 프로세스는 init데몬이
부모프로세스가 되는걸로 알고 있습니다... 제가 잘못 알고 있는건지
모르겠네요...
[quote="yisuyong"]그런데 제가 말 했듯이 /etc/rc.d
맞습니다. 부팅시 실행되는 rc script는 init에 의해 호출됩니다. 그래서 부모프로세스가 init이 되는거구요. 실행당시 제어터미널이 없기 때문에 데몬화 시키는것과 동일한 효과가 있겠네요.
pts/0이 닫혔을때 프로그램이 죽는 경우는 해당 프로그램이 pts/0 터미널 상에서 실행이 된 경우, 그리고 터미널이 닫혀도 프로그램이 죽지 않도록 조치를 취하지 않은 경우입니다.
======================
BLOG : http://superkkt.com
[quote="superkkt"]몇 페이지에 그런 내용이 있나요?
APUE 417p에 보면
5. Unneeded file descriptors should be closed. This prevent the daemon from
holding open any descriptors that it may have inherited from its parent.
라고 적혀 있는데
제가 잘못 해석했군요 :oops:
저기서 holding은 have의 의미로 쓰인건데 저는 stop의
의미로 생각했습니다.
어쨌건, 책에는 왜 디스크립터들을 다 닫아야 하는지 않나와서
그거 느무느무 궁금합니다 ^^
(제가 짠 프로그램중에서도 분명히 아무론 조치를 하지
않았슴에도 -제가 100퍼센트 다 짠게 아니라서 정확히는
모르겠지만- 데모나이즈 하지 않고 백그라운드로 돌려도
아무렇지도 않게 잘 돌아가는 경우가 있어서
의문을 가졌습니다.)
제가 전에 이 문제에 관해 질문을 한적이 있었음에도
답변이 안올라 온것으로 기억합니다 ^^
C++, 그리고 C++....
죽어도 C++
저도 정확히는 모르는데요...전에 데몬에서 표준 입/출력/오류 를 닫
저도 정확히는 모르는데요...
전에 데몬에서 표준 입/출력/오류 를 닫지 않았더니 데몬이 잘 돌다가 갑자기 죽어버리는 현상을 경험한 적이 있습니다. 그때 한참 삽질을 했었는데...
알고보니 원인이 printf때문이더군요. (제어터미널이 없는 데몬이 printf를 찍으면 그 출력된 내용이 어디로 갈까요?)
그때는 데몬을 터미널에서 실행시키면 안죽는데, 다른 데몬이 start시켜주면 죽더군요... 표준입출력을 close시켜주고 나니 문제가 없어졌습니다.
그 외에도 여러가지 예상치 못한 상황이 생기는것 같습니다.
아는 선배님 한분은...
inetd가 띄워주는 데몬을 만들었는데... 자꾸 프로그램이 이상하게 동작해서 디버깅하다보니.. printf로 출력한 내용이 0번 socket으로 되돌아오고 있더라는 얘기를 하시더군요.... :)
----------------------------------------------
한번뿐인 인생....
미친듯이 살아보자!
----------------------------------------------
이거 이런게 간단한 프로그램도 문제가 많은거 같은데큰일이네요...
이거 이런게 간단한 프로그램도 문제가 많은거 같은데
큰일이네요... :cry:
데몬의 의미.
데몬은 새로운 세션에서 작동하며, 제어 터미널을 지정하지 않은 경우입니다.
제어 터미널을 지정해서 가지게 되면, 같은 세션내의 같은 프로세스 그룹은 몇몇 시그널을 전파(e.g. SIGINT)하는 기능이 있습니다. 이를 통해서 정상적이지 못한 상황에서 제어터미널을 지닐 프로세스가 시그널을 받았을때 같이 죽는 경우가 발생합니다.
이를 방지하기 위해서 데몬프로세스는 새로운 세션을 생성하며, 세션이 생성되면 자동으로 프로세스 그룹도 생성되며, 제어터미널이 없으니 프로세스그룹의 시그널 전파로 죽을 염려가 사라지죠.
이게 데몬화의 이유입니다.
========================================
* The truth will set you free.
[quote="superkkt"]또한 데몬은 터미널이 없기 때문에 입출력
한마디로 ps 명령어로 봤을때 터미널 값이 '?' 물음표로 나오면
된다는 예기죠??
맞습니다.
빙고~
========================================
* The truth will set you free.
Re: 데몬의 의미.
듣고싶어던 시원한 대답입니다.
제가 오해 하지 않은것인가 한번만 더 확인하자면
1. 특정 시그널은 프로세스 그룹으로 전파되는 특성을 가지고 있다.
-> setsid()등으로 새로운 프로세스 그룹을 만들고 자신이 그룹리더가 되어 특정 그룹에서 빠진다.
2. 제어 터미널이 있을때 특정 시그널을 받으면 죽을 수도 있다
인가요?
한마디로 1번이 잘 되어있으면 터미널을 죽이는게 굳이 필요없는 기능인가요?
물론 저는 코딩할때 파일 디스크립터들을 모두 닫을 겁니다.
그러나 그거와 별개로 사실 너무 궁금해서 :oops:
C++, 그리고 C++....
죽어도 C++
간단하게 테스트 해보시면 됩니다.
간단하게 fork 몇개 하는 프로그램을 만들어 보시기 바랍니다.
그 후에 프로세스 그룹 리더를 Ctrl-C (SIGINT) 로 죽이면 모든 자식 프로세스가 같이 죽습니다. 그러나 SIGTERM 으로 죽이면 부모만 죽고 자식은 모두 고아 프로세스가 되어 스텝패어런츠로 INIT 가 되죠.
그리고 터미널을 죽인다는게 무슨 의미인지 잘 모르겠습니다. 데몬화하고 터미널 죽일 필요는 없습니다.
실제로 데몬 프로그램을 만든 경우에는 1, 2 번 fd 는 대부분 다른 쪽으로 리다이렉션 해둬서 로그파일에 기록하는 경우가 대부분입니다. 혹은 필요 없다면 닫아주시고 그쪽으로 출력을 안하면 되겠죠.
만일 데몬화를 잘못하여, 제어터미널을 가진 상태로 백그라운드에서 작동하면서 출력을 잘못하는 경우에 SIGTTIN, SIGTTOU 시그널을 발생시켜서 프로세스를 STOP상태로 만드는 경우가 발생할 수 있으니 기본적으로 이를 조심해주시면 됩니다.
========================================
* The truth will set you free.
[quote="kuaaan"]저도 정확히는 모르는데요...전에 데몬에
바로 그런 문제때문에... 스티븐스의 책 개정판을 보면 이전판의 daemon_init 함수가 수정된 것을 확인하실 수 있습니다.
즉, 0/1/2 를 아예 미리 오픈한후 /dev/null 로 보내버려서 데몬과 다른 라이브러리 간에 디스크립터 충돌을 막자는 거죠.
(28-32 라인)
[quote="ixevexi"]어쨌건, 책에는 왜 디스크립터들을 다 닫아
stdin stdout stderr 사용해도
OS 에 따라서는 잘 작동합니다.
경험상으로 리눅스는 잘 작동하고, 솔라리스는 죽더군요.
이것 때문에 솔라리스에서 cron 으로 돌리는게 잘 작동안해서 애를 먹었던 기억이 있네요.
쉘에서 실행하면 잘 작동하는데, cron 으로 스케쥴링해 놓으면 작동 중간에 죽어 버리더군요.
자원의 소비 관점에서 보면
불필요한 자원은 최대한 제거하겠다는 의미도 있을 듯 합니다.
FD_SET 은 기본으로 1024 개 를 처리하는데
stdin, stdout, stderr 이 3개 차지하면 1021 개 사용하니깐
3개가 아깝자나요.
select 사용할 때도 fd 0 부터 체크를 하는데
불필요한 체크를 in 이벤트에서 3번, out 이벤트에서 3번을 하게 되기도 하고요.(예외 이벤트 사용한다면 것두 +3)
PS. 별거 아닌 FD 3개 갖고 넘 째째하게 굴었나요? ^^
댓글 달기