쓰레드 환경에서 waitpid에 관해서.. ?
글쓴이: partout / 작성시간: 화, 2003/10/14 - 12:10오후
하나의 쓰레드에서 차일드 프로세스를 생성하고,
다른 쓰레드에서 이 차일드 프로세스에 대해서 wait하면.. wait이 실패하더군요.
가령, 프로그램이 구동될 때 작업 쓰레드를 하나 생성하는데...
이 작업 쓰레드가 쓰레드는 파일에 기록된 이전 상태를 확인하고
필요한 경우 차일드 프로세스를 fork합니다.
이 후에 사용자로부터 접속이 있으면 이를 처리하기 위한 핸들러 쓰레드가
하나 생성되고, 사용자가 현재 구동 중인 차일드 프로세스를 종료시키기를 원하면
TERM 시그널을 날려 프로세스를 종료시키고, 좀비를 막기 위해 waitpid를
호출합니다. 문제는 여기 waitpid에서 항상 실패합니다.
errno 값을 찍어 봤는데 ECHILD(10)이더군요. waitpid 하려는 프로세스가
자신의 child가 아니라는 것 같은데...
이것은 리눅스의 쓰레드가 쓰레드마다 하나의 프로세스를 할당하기 때문에
다른 쓰레드가 fork한 차일드 프로세스를 자신의 차일드 프로세스로
인식하지 못하는 것 때문인 것 같더군요.
저는 이러한 상황을 좀 깔끔하게 해결할 수 있는 방법이 궁금합니다.
그냥 저는 작업 쓰레드 쪽에서 주기적으로 waitpid를 호출해서 좀비를
해결할까도 생각해 봤는데,... 그것보다 더 좋은 방법이 있을 것 같아서..
가령.. 다른 쓰레드에서 생성한 차일드 프로세스를 자신의 아이로 인식시킨다던가...
답변 부탁 드립니다.
Forums:
일반적으로..
ECHILD 는 리턴할 값이 없을때 errno에 세팅됩니다.
쉽게 말해 SIGCHLD가 오지 않았다는..
SIGCHLD를 sigismember로 시그널 마스킹 했는지 확인해보시죠.
SIGPFE, SIGSEGV같은 동기화 "하드웨워"문맥 시그널을 해당하지
않으면 어느 쓰레드로 시그널이 전달될지 알수 없습니다.
즉 SIGCHLD는 어느 쓰레드로 전달될지 장담 할수 없습니다.
일반적으로는 메인쓰레드에서 pthread_sigmask 를 통해 시그널을 마스킹 하고 다른 전담 쓰레드에서 sigwait를 통해 시그널을 동기적으로 처리하는것을 권고 하고 있습니다.( POSIX THREAD PROGRAMING )
브이 V
답변에 감사 드립니다. 많은 도움이 되었습니다. ^^하지만, 정작
답변에 감사 드립니다. 많은 도움이 되었습니다. ^^
하지만, 정작 문제가 되었던 부분은 해결을 하지 못했습니다.
말씀하신대로 모든 쓰레드에서 시그널을 masking하고
시그널 처리를 전담할 쓰레드에서 아래와 같이 작성된 함수를
호출해서 시그널을 처리하도록 했습니다.
하지만, 문제는 다른 쓰레드에서 생성한 차일드 프로세스를
종료시켰을 경우에 이 전담 쓰레드로 시그널이 전달되지 않네요.
차일드 프로세스가 종료되었을 때 SIGCHLD 시그널은 차일드를
생성한 프로세스가 아니라 차일드 프로세스를 생성했던 쓰레드로만
전달이 되는 것 같습니다. 단지 추측이라 맞는 얘기인지 모르겠네요.
혹시, 이 부분에 대해서 아시면 답변 부탁드리겠습니다.
이런 상황을 해결할 수 있는 방법에 대해서도 답변해 주시면 더 감사하구요. ^^
어찌나 졸린지..~~
마땅한 해결책을 찾지 못해서... 처음 생각했던대로..차일드를 포크하
마땅한 해결책을 찾지 못해서... 처음 생각했던대로..
차일드를 포크하는 작업 쓰레드에서 주기적으로
아래와 같은 구문을 실행시켜서 zombie를
정리하도록 했습니다.
while (waitpid(-1, NULL, WNOHANG) > 0) (void *)0;
시간이 나는대로 관련된 자료를 찾아봐야 할 거 같네요.
어찌나 졸린지..~~
댓글 달기