SIGNAL의 동시처리 방법
글쓴이: danielkim / 작성시간: 금, 2003/12/12 - 3:55오후
안녕하십니까?
Daniel Kim 입니다.
거의 동시점에 발생하는 SIGCHLD 의 처리 방법에 관한 의견을 구합니다.
void process_childdead(int sig) { // to do something work that takes a litte long time waitpid(... ... } void main ( ) { .... signal(SIGCHLD, process_childdead); .... // 여러개의 child process 를 동시에 fork한다. exec_childs(.... ) }
위의 형태의 코드가 있을때 process_childdead 코드 내에 약간의 시간이
걸리는 코드가 들어가 있다고 가정합니다.
이때 exec_childs 에서 수행한 child1, child2, child3 , ... ... childN 입니다.
이때 child1의 prcess_childdead를 수행하는 도중 child2가 죽는 다면
과연 어떻게 처리해야 할까요?( 저는 현재 약간의 꼼수로 이러 처리한 상태입니다)
현재까지 제가 테스트한 결과를 보면 child2는 [defunc] 로 처리가 되는 군요
이걸 피할 방법을 찾고 있습니다.
많은 의견 기대합니다.
답변 주신분들께 미리 감사 드립니다.
-------------------------------------------
Forums:
많은 유닉스 커널에서 시그널은 큐로 관리되지 않고, 비트 플래그로 기록되
많은 유닉스 커널에서 시그널은 큐로 관리되지 않고, 비트 플래그로 기록되기때문에 한 시그널의 여러 인스턴스가 발생해도 시그널 핸들러는 한번밖에 수행되지 않습니다.
게다가 시그널 핸들러 수행도중에 시그널이 또 발생하면 핸들러 수행이 중단됩니다. 이것을 막기 위해선 POSIX sigaction() 을 사용하거나, 시그널 핸들러 시작시에 해당 시그널을 블록해줍니다.
여기까지는 교과서에 나오는 것을 베낀것이구요.
여러개의 시그널이 중첩되어 있는 경우의 처리는 루프를 돌면서 가능한 시그널 발생 요인을 모두 확인, 처리해주면 되지 않을까요?
다음과 같이 하면 되지 않을까요...저것도 꽁수라 하시면 할말은 없지만.
다음과 같이 하면 되지 않을까요...저것도 꽁수라 하시면 할말은 없지만....ㅡㅡ;;
인간에게 있어 열정은 둘도없이 소중한 것이다. 경력이나 학력보다도... - 월리엄 록펠러 1세 -
[quote="zeroness"]다음과 같이 하면 되지 않을까요...저것
꽁수가 아닌듯..
----------------------------------------------------------------------------
만약 사용하시는 시스템이 solaris이고,child의 exit st
만약 사용하시는 시스템이 solaris이고,
child의 exit status 는 상관이 없으시다면, sigaction의 SA_NOCLDWAIT 를 사용하시면 됩니다..
--------------------------
Donghyun Jung
..
약간 다른 시각이지만.
추가적으로
parent가 종료하기 직전에도 wait() 돌려주는 건 어떨까요?
defucnt로 걸려있는 child들을 모두 수거할 수 있지 않을까요?
좋은 제안들에 감사합니다.
daniel Kim 입니다.
여러분들이 주신 좋은 제안들 감사합니다.
조인씨에 가보니 좋은 강좌가 있네요~www.joinc.co.kr 에서
조인씨에 가보니 좋은 강좌가 있네요~
www.joinc.co.kr 에서 "시그널" 또는 "SIGNAL" 으로 검색해
보세요.. ^^
인간에게 있어 열정은 둘도없이 소중한 것이다. 경력이나 학력보다도... - 월리엄 록펠러 1세 -
동시에 여러개의 시그널이 발생 하는데, 예를 드신것 처럼, SIGCHLD
동시에 여러개의 시그널이 발생 하는데, 예를 드신것 처럼, SIGCHLD가 거의 동시
적으로 발생 할 경우 에 대한 것이라고 생각 하고 제가 사용 하는 방법을 적어
봅니다.
예를 들어 100개 혹은 200개 이상의 자식 프로세스가 언제 종료 될지 모르는
상황에서 프로세스가 관리 되고 있다고 생각하겠습니다.
기본적으로 시그널 처리 함수 부분.
대충 처리 함수는 이상과 같이 사용 하면 되지 않을 까 생각 합니다./* 시스템에 따라 정의 안되어 있는 경우 있슴 */
더 좋은 방법을 알고 계시다면,... 가르쳐 주시면 감사 하겠습니다.
그리고 저렇게 대규모의 자식 프로세스를 관리 한다는 것은 언제나,
좀비가 발생할 가능성이 있습니다. 그러니 메인 프로세서에서는 정기적으로
raise(3)등의 함수를 이용하여 자기 자신에게 시그널을 보내 주면, 대부분의
경우 해결이 가능 할듯 합니다.
raise(SIGCHLD);
뭐 이런식이면, 아래의 시그널 처리 함수로 들어 가게 될것이고, 좀비화 되어
있는 자식들을 거두어 들일수 있습니다.
>>>행복한 웃음<<<
sender_sigchld는 무엇인가요?
안녕하세요.
sender_sigchld는 무엇인가요?
sender_sigchld는 정의되어 있지않아서 소스를 이해할수 없습니다.
제가 초보라서 풀 소스를 보여주시면 안될까요?
OTL 즐!!!! (좌절 금지!!!)
음 죄송합니다. 이 부분은 저의 실수 이군요.--> 버그 입
음 죄송합니다.
이 부분은 저의 실수 이군요.--> 버그 입니다.
지금 짜고 있는 프로그램의 SIGCHLD처리 부분을 그냥 가져다 붙이다 발행한
일반적인 카피 페이스트 오류라고 할 수 있습니다.
process_childdead 이 맞습니다.
보다 자세한 사항들은 man (man waitpid)을 이용하여 보십시오.
>>>행복한 웃음<<<
[code:1]게다가 시그널 핸들러 수행도중에 시그널이 또 발생하면
이게 정확한 내용인가요? 제가 알고 있기론 signal handler 가 수행되는 동안에는
그 signal 이 블럭 된다고 알고 있는데요.
SIGCHLD 가 문제가 되고 child process의 종료 상태에 관심이 없으시다면..
프로그램 시작시..
을 추가해주시면 될 것입니다.
[quote="vinus"]음 죄송합니다. 이 부분은 저의 실수
waitpid() 의 리턴값이 0보다 작은 경우에만 시그널 핸들러를 빠져나가는 것은
가끔 문제를 일으킬 수 있습니다.
아래 스레드를 보시면 정확히 waitpid()가 0을 리턴했는지는 원제출자가 명시를
해주지 않아서 확실치는 않지만, waitpid가 0을 리턴한 경우로 추측되어서
시그널 핸들러에서 상당한 시간을 잡아먹는 경우를 보실 수 있습니다.
http://bbs.kldp.org/viewtopic.php?t=39299
시그널처리함수에서 시그널을 꼭 재설정 해야하나요?
바쁘신데 죄송합니다. 다른 질문이 생겼는데요.
시그널처리함수에서 시그널을 꼭 재설정 해야하나요?
그리고 제가 실험삼아 시그널 처리함수가 언제 호출되는지 알아봤는데요.
자식 프로세스가 죽지 않았는데도 호출이 됩니다. 이유가 무엇인가요?
OTL 즐!!!! (좌절 금지!!!)
merge된 시그널 처리는
보통 윗분말씀대로 거의 동시에 발생된 SIGCHLD가 merge되어 나올때는 시그널 핸들러를 waitpid로 처리하는게 맞습니다. 다만 조금 첨언을 달면
waitpid() 처리시에 WNOHANG외에 WUNTRACED를 같이 넣어서 멈춰있는 녀석과 처리지연이 없게 해야 합니다. 또한 waitpid()의 반환값도 0이나 -1을 다 검사해야 합니다.
waitpid()는 WNOHANG에 의해서 어떤자식도 죽은적이 없다면 0을 종료된 자식의 프로세스 ID가 에러종료이면 -1을 반환하기 때문입니다.
또한 정상적인 종료가 아닌지를 판단하기 위해서 WIFSIGNALED()매크로를 이용해서 검사해주는 것도 필요하지요. 나머지는 대부분 WIFEXITED()매크로에 검출되니까 별 문제는 없습니다.
PS) 시그널핸들러의 블럭킹은 조금 다른 문제입니다. 기본적으로 시그널핸들러는 시그널을 블럭하지 않습니다. 시그널을 블럭하느냐 마느냐는 sigset_t 형의 매스크를 만들어서 블록을 하는가에 따르기 때문입니다.
========================================
* The truth will set you free.
signal보단 sigaction()을 쓰기를..
signal()보단 sigaction()을 쓰기를 권장합니다.
signal()함수는 머신에 따라서 일회적으로 사용되고 핸들러가 재설정되기도 합니다. 따라서 정확한 시그널 핸들링을 위해서는 sigaction()을 쓰기를 권장합니다.
========================================
* The truth will set you free.
답변 주신 분들께 감사드립니다.
좋은 하루 되세요. :)
OTL 즐!!!! (좌절 금지!!!)
sunyzero님 답변 감사합니다.[code:1]기본적으로 시
sunyzero님 답변 감사합니다.
테스트 한 결과..
implemetation 마다 다른 것 같군요.
linux와 SunOs도 다른 것 같습니다.
[code:1]waitpid()는 WNOHANG에 의해
어떤 자식이 죽은적이 없다면 0을 리턴하는 것이 아니라 어떠한 child process도 남아있지 않다면 0을 리턴하는 걸로 알고 있는데요.
따라서 보통..
SIGCHLD가 폭주할 경우에..
으로 처리하는 것으로 알고 있습니다.
댓글 달기