linux 의 thread 질문입니다. - zombie 되는 현상때문에...
글쓴이: realmacpro / 작성시간: 수, 2003/08/20 - 3:58오전
안녕하세요.
게시판을 살펴보다보니 linux 에서 thread 를 사용하게 되면 thread manager 라는 thread(process) 가 하나 생긴다는 것을 알게 되었습니다.
이것 때문에 한참을 고민했었는데 해결되니 한결 나아졌는데 아래의 문제가 남아 있습니다.
그 thread manager 에 관한 질문인데요,
프로그램이 실행중에 thread manager 에 해당하는 process 가 간혹 zombie 가 되어 버리는 현상을 보게 되는데 signal handler 에도 나타나지 않기 때문에 어떤 시점에서 어떤 시그널을 받아 좀비가 되는지 알 수가 없습니다.
thread manager 의 동작을 디버깅할 수 있는 방법은 없는지?
아니면 thread manager 가 어떤 경우에 kill 이든 어떤 시그널을 받아 좀비가 되는지 궁금합니다.
시험을 해보니까 thread manager 는 kill -9 (pid) 를 하면 항상 좀비가 되어 버립니다.
다른 시그널은 받아들이지 않는 것 같구요...
답변을 부탁드립니다.
그리고, thread manager 생기지 않고 thread 를 사용할 수 있는 방법은 없나요? 사용중인 커널은 2.4.0에 pthread 는 0.8, gcc 버전은 2.95.2 입니다만 개발환경을 바꾸지 않고 변경할 수 있는 방법이면 더욱 좋겠네요.
Forums:
Re: linux 의 thread 질문입니다. - zombie 되는 현상때문에...
*유닉스의 대전제
1) 모든 유닉스 프로세스는 부모/자식의 관계를 갖는다.
2) 부모자식은 트리구조로 표현된다.
3) 트리의 루트는(모든 프로세스의 대부는) init이다.
4) 모든 프로세스는 정수값의 고유식별자를 갖는다.
- init의 process id (pid) 는 1이다.(다른 프로세스, 즉, init의 후손은 > 1인 정수값을 pid로 갖는다.
* zombie를 이해하기 위해
1) 부모는 자식프로세스가 죽을 경우, 이에 대해 알고 있어야하고 이에 대한 처리를 수행해야한다.
- 딱딱하게 얘기하면 자식프로세스는 항상 자신의 죽을때(버그나, 아니면 인위적, 프로그램코딩상등등으로) 자신의 부모에게 시그널을 보내게 되어있다.
- 반면, 부모는 자신의 자식프로세스가 죽으면서 보내온 시그널을 받게 되어있다.
- 부모가 자식프로세스의 시그널(SIG_CLD)을 받고 이에 대해 처리를 해주지 않으면(시그널핸들러를 안달아주면), 자식은 부모로 부터 죽음조차도 외면당한 상황이 된다. 이럴경우 한이 맺혀서 좀비로 남아 이승을 떠돌게 된다.
우스개소리였고요, 부모는 자식프로세스를 모니터링할 의무가 있습니다. 이러한 것은 코딩의 전통이라고도 볼수있습니다. 다중프로세스로 프로그래밍할때는 자기 자신이 생성한 프로세스가 잘 돌고 있는지를 모니터링하는것은 필수지요. 모니터링방법은 다양하겠지만, 적어도 자식프로세스가 죽었는지 살았는지정도는 파악해야한다는 명제를 유닉스 제작자가 좀비라는 명칭으로 계도했다고 생각하십시요.
* 참고
1) init(1번) ; 모든 프로세스의 원조; 대한민국 신화적으로는 단군;이 죽는것은 시스템이 죽는것을 의미
2) 부모가 자식보다 먼저죽는다면?(물론, init제외한)
- 자식은 고아가 되므로 당연히 고아원으로 보내던가 부양받을 곳으로 보내는게 정상이며, 유닉스는 이를 init가 담당하도록 하고 있습니다. 즉, 자식프로세스를 거느린 부모가 죽으면 자식프로세스의 부모는 모두 init(1번)으로 세팅됩니다. init가 부모가 되는것이지요. init는 기본적으로 자식프로세스의 사망시그널에 대한 처리를 수행하게끔 이미 만들어져 있습니다. 그러니, 프로세스의 대부지요.
* 결론
따라서, 지금 좀비가 되는 프로세스의 부모에서 SIG_CLD에 대한 처리를 해주면 좀비가 안되게 되겠지요. 핸들러내에서는 해당 자식의 유고에 따른 처리(복구?)등을 해주던가 하면 되겠네요.
------------------ P.S. --------------
지식은 오픈해서 검증받아야 산지식이된다고 동네 아저씨가 그러더라.
signal handler 중에 SIGTERM 을 등록해서 쓰는데...
도움 감사합니다.
그런데, 제가 궁금한 사항을 다시 설명하면...
프로그램 실행시에 thread 마다 pid 를 찍도록 했기 때문에
어떤 thread 가 나타나는지 알 수 있습니다.
그리고 제가 작성한 코드에는 SIGTERM 을 받았을때 동작하도록 signal handler 가 추가되어 있습니다.
그런데, 모든 thread (process) 는 외부에서 kill -9 pid 를 보내면,
SIGTERM 을 받았기 때문에 signal handler 의 처리가 나타납니다.
그런데, thread 동작시 pid 로 나타나지 않는 thread manager 에 해당하는 thread 만 외부에서 kill -9 pid 해봤자 signal handler 가 처리하지 못하는 상태로 나타납니다.
댓글 달기