zombie (좀비) 프로세스 문제
횡설 수설해서 아래 댓글로 질문을 정리하였습니다.
---------------------------------------------
*이건 처음 올린 질문입니다.
안녕하세요? 매번 해당싸이트에서 좋은 정보 얻고 있는 초보 프로그래머 입니다.
리눅스(데비안)에서 프로그래밍 중 좀비프로세스 문제때문에 이렇게 글을 올립니다.
간단한 쉘 프로그램(A)을 하나 만들어서
B 라는 프로세스를 실행시키고 있습니다.
B는 사실상 무한 대기하는 서버 프로그램입니다.
쉘(A)를 이용하여
B가 실행되고 있는지 확인하고 (ps 명령 조합으로 확인)
B가 실행되고 있으면 B를 종료 시키고 (kill -9 프로세스 아이디) 다시 실행
B가 실행되고 있지 않으면 실행시키도록 while로 반복시켜놨습니다.
따라서 B 프로그래밍이 뻗어도 자동으로 A가 살리도록 해놨는데..
가끔 B가 알수없이 죽어서 갑자기 종료되고 좀비프로세스(ps로 쳐보면 defuct라고 나오더군요)가 되는 경우가 있습니다.
여기서 B의 부모 아이디(ppid)는 A인 상황입니다.
결국 kill -9 로 좀비 프로세스(B의 pid)를 죽일수 없는 상황이고 (kill -9 pid 를 쳐도 아무 반응 없이 그대로 살아있음)
좀비 프로세서의 부모(A)를 죽여야 B도 죽일수(kill) 있는 상황인데
만약 B가 예기치 못하게 뻗으면 A,B 모두 죽여야기 때문에 B의 프로세스를 계속 돌릴수가 없게 되더군요
물론 애초에 B라는 프로그램을 잘 만들면 문제가 없겠지만 최후의 보루로 A를 돌리기를 원하고 있는 상황입니다.
이런 경우 좀비 프로세스를 죽일 때 부모프로세스를 죽이는 방법 말고는 방법이 없는건지요?
또는 이런 현상을 해결할 묘책(?)은 없는지도 궁금합니다.
많은 조언 부탁드립니다.
읽어주셔서 감사합니다.
읭?
A는 그럼 계속 켜져 있으면서 while로 무한 루프 돌면서 B를 계속 죽였다 살렸다 하는거에요? 제가 잘못 이해한 건지...?
A는 쉘 스크립트죠? B를 아마 백그라운드로 실행시킬 것 같은데, 직후에 wait명령 때리면 B가 죽을 때 알아서 깨어납니다. 그 때 다시 실행시키면 되죠. while loop으로 busy waiting할 필요가 전혀 없어요.
게다가 부모가 wait 해줌으로써 좀비상태가 안 되는 이점은 덤.
답변이 좀 성의없어 보일지도 모르겠는데 지금 질문 내용 가지고 파악할 수 있는 게 별로 없네요. 혹시 A 스크립트 내용이라도 공개해 주실 수 있으신지요?
안녕하세요? 질문자입니다. 제글에 답변을 주셔서
안녕하세요? 질문자입니다.
제글에 답변을 주셔서 너무나 감사드립니다.
바보같이 쉘 스크립트 올리면 될 것을 말로 설명해 버렸네요
위에 질문은 횡설수설인거 같으니 이 글 참고 바랍니다.
위 질문을 다시 요약 드리면요
아래의 A스크립트로 B(끝없는 서버 프로그램)라는 프로그램을 실행시키고 있습니다.
만약 B가 실행되고 기대하지 않게 종료되면 다시 실행되도록 되지요
아래는 A 스크립트의 내용입니다.
#!/bin/bash
while [ 1 ]
do
pid=`ps -ef | grep B | grep -v 'grep' | awk '{print $2}'`
echo $pid
if [ -z $pid ]; then
./B #여기서 B를 실행하면 정상적으로 동작하는 한 여기서 멈춰있음
음음
else
echo "Aready Start B"
kill $pid #좀비 프로세스는 pid만으로 죽일 수가 없음
fi
sleep 5
done
스크립트를 보시면 만약에 B가 기대하지 않게 죽으면 (이때 좀비 프로세스가 됨)
A스크립트에서는 프로세스가 살아 있는지 확인하고
B는 (좀비로) 살아있기 때문에
프로세스를 죽이려고 합니다. (kill $pid)
하지만 좀비라 죽지 않습니다.
그래서 결국은 좀비 프로세스 때문에 B라는 프로그램은 계속 실행되지 못하는 상황입니다.
물론 여기서 좀비 프로세스의 ppid(부모아이디)를 kill 하면 되겠지만
ppid가 A스크립트이므로 전체가 결국 멈추게 되게 됩니다.
좀비 프로세스가 생성되었을 때 A스크립트를 이용하여
다시 좀비 프로세스를 죽이고 B를 실행할 방법이 없는지요?
긴글 읽어주셔서 너무나 감사드립니다.
초보에게 많은 조언 부탁드립니다.
혹시, 여러개의 A를 실행시키고 있진 않나요? 직접
혹시, 여러개의 A를 실행시키고 있진 않나요?
직접 해보니 잘 됩니다.
가능한 시나리오는,
1. A를 실행시키고, (누군가) Ctrl+Z를 눌러서 원래의 A는 정지된 상태. 이순간 B도 정지됩니다.
2. (누군가) B가 잘돌아가지 않다는걸 찾았거나, 그냥 심심해서 A를 또 실행해봅니다.
3. 새로 실행된 A는 이미 B가 실행되어있다는것을 찾고, B를 kill -9로 죽임
4. 기존의 B는 죽었지만, 처음실행되었던 A는 정지되어있는 상태라(Ctrl+Z) B가 죽은걸 모르고, 그냥 좀비로 냅둠.
5. 새로 실행된 A는 기존의 B를 자꾸 죽이려고 kill -9를 보내는데, #1에서 실행된 B의 부모(원래의 A)가 거두어들이지 않아, 계속 좀비를 죽이려고 반복함.
해당 문제가 생길때, ps aux | grep A 해서 몇개의 A가 돌아가고 있는지 살펴보세요.
자식프로세스가 죽었을때 부모가 거두어들이지 않는다면, 부모가 무응답 상태에 빠져있을 상황이 대부분입니다.
댓글 달기