[질문] fork 후 signal 을 이용한 좀비처리.
글쓴이: psjHello / 작성시간: 토, 2003/11/08 - 7:27오전
fork() 로 생성되어진 자식프로세스가
작업을 마치고 SIGCHLD 를 발생시키고
죽었을때,
signal (SIGCHLD, (void*) zombie_remover);
를 사용해서 좀비처리를 하려고 합니다.
fork() 가 어느정도 여유를 두고 호출될 경우에는
만족스럽게 동작합니다만...
소켓으로 서버를 짜던 도중,
소켓클라이언트로 부터 '한꺼번에 많은 요청' 을 받게되어
짧은 시간내에 많은 fork() 를 호출해야 할 경우에
좀비들이 많이 생겨나는데요...
자식이 죽을때마다, 죽는자식의 정확한 수만큼
SIGCHLD 를 받아서, 정확한 수만큼 핸들러를
호출하는 것이 아닌지 궁금하네요.
---------------------------
의심이 가는건, 프로그램이 블록된 상태에선
중복된 signal 이 중간중간 drop 되어진다는 것을
어디선가 들은것 밖에 없는데요...
---------------------------
저 같은 경우에
'signal(SIGCHLD ....) 外에, 또 다른 좀비제거-루틴'
을 <두 개 모두 같이> 사용해도 괜찮은 것인지요...
답변 달아주시면 감사하겠습니다...
Forums:
SA_NODEFER
시그널이 프로세스에 도착했을때..
만약 프로세스가 이 시그널을 블럭킹하기로 설정했다면
이 시그널은 프로세스의 '시그널대기큐'에 저장됩니다.
기본적인 사항...........을 먼저 말씀드리면...
근데...이 시그널 대기큐에는 같은 종류의 시그널이
여러개 있는 경우는 없습니다. 한 종류마다 최대 한개입니다.
여러개 도착해도 쌓이지 않는 다는 것이죠
옵션적인 사항........
근데...쌓이게 할수도 있습니다.
SA_NODEFER 플래그를 설정해서 가능합니다.
한가지 ..여러 문서들을 읽어보면...더이상 signal 함수를
사용하지 말것을 권장하고 있습니다.
signal 함수를 통해서는 SA_NODEFER 플래그를 설정할
방법이 없거든요
signal 함수는 옛날의 코드와 호환성을 위해 남겨둔 함수라고 합니다.
sigaction 함수를 사용하라고 하네요.
sigaction 함수는 포직스 표준으로...
솔라리스,리눅스, BSD등의 운영체제들이 잘~ 따르고 있는
표준입니다.
sigaction 함수를 사용하면 SA_NODEFER 플래그를 설정할 수 있습니다.
man sigaction 하면 잘나옵니다.
저도 궁금해서 테스트 해보았는데요
리눅스에서 SIGCHLD는 다른 시그널과 마찬가지로
대기큐에 한번만 쌓이게 됩니다. 하지만 SA_NODEFER 플래그를 설정하면
도착한 시그널의 개수만큼...( 큐에 쌓여서 ) 핸들러를 호출해줍니다.
솔라리스7 에서는 기본으로 SIGCHLD는 명시하지 않는다해도
SA_NODEFER 플래그를 설정한 것과 동일한 동작을 하네요
제생각에 리눅스든 솔라리스 7이든.. SIGCHLD개수만큼
핸들러를 호출하려면
SA_NODEFER 플래그를 설정하면 동작이 잘될것 같습니다.
다른 OS에서는 테스트 못해봤습니다.
참고로 제가 테스트 해본 코드입니다.
잘못된부분있으면 알려주시면 감사드리겠습니다.
waitpid로 검색해보시죠.. :)거의 FAQ 입니다..
waitpid로 검색해보시죠.. :)
거의 FAQ 입니다..
---
http://coolengineer.com
시그널 핸들에서 다음과 같이 써 보세요.while (waitpid
시그널 핸들에서 다음과 같이 써 보세요.
while (waitpid(-1, NULL, WNOHANG) > 0) (void *)0;
어찌나 졸린지..~~
댓글 달기