이번 글에서는 간단하게 좀비 프로세스에 대해서 알아보도록 하겠습니다. ps 명령어 사용법도 익히실 겸 겸사겸사. 이것은, 실행이 다 끝났는데, 아직 어딘가에서는, 삭제가 되지 않은, 정보가 남아 있는 프로세스를 의미합니다. 이들을 여러개 생성해 보면서 어떤 일이 일어나는지 보도록 하겠습니다.

 

 


 fork.c 프로그램입니다. 이것을 보면, pid가 -1일 때, while(1) 1번째 LOOP를 빠져 나옵니다. 이 때에는 프로세스를 생성할 수 없을 때일 거고요. fork()를 호출한 경우, 자식 프로세스가 생성이 되는데요.

 

 

 이 때, 부모인 경우, pid 값이 0이 리턴이 되지 않기 때문에, 계속 while Loop를 돌 겁니다. 그러다가 fork 함수가 -1을 리턴한다면, (예를 들자면, 프로세스를 생성할 수 없다면) 빠져 나올 거에요. 그리고 2번째 while(1) Loop를 도는데요. 부모 프로세스를 강제로 종료하지 않는 이상, 계속 돌 거에요. 그렇다면, 자식이 부모보다 먼저 종료가 될 거에요. 이 부분은 부정하지 못하는 사실입니다.

 

 

 그러면 이 때 어떻게 될까요? 특별한 설정을 하지 않았다면, 자식 프로세스에 대한 정보가 남아있을 거에요. 자식 프로세스는 종료가 되었는데도 불구하고요. 실제로 이 프로그램을 실행을 시키고 ps -au 명령어를 쳐 보면 아래와 같이 나옵니다.

 

 

 stat에 Z+이라고 표시된 무언가가 보입니다. 2번째 열은 pid인데요. 9546, 9547, ... , 9567번 프로세스가 좀비 프로세스라는 이야기입니다. 분명한 것은 이들은 이미, 종료가 되었다는 것입니다. 계속 이런 식으로 쌓이면 어떻게 될까요?

 

 

 당연하게도, 자원이 사용 불가능하다고 뜹니다. 좀비 프로세스도, 뭔가를 차지한다는 이야기입니다.  리눅스의 man page에 따르면 zombie는 process table의 slot을 차지한다고 되어 있어요. 이것이 꽉 차면, 추가로 프로세스를 생성하지 못합니다. 이는, 부모 프로세스에서 자식 프로세스의 종료 상태를 확인할 수 있게 하기 위해서입니다. 부모가 wait나, waitpid와 같은 함수를 쓴다면 이야기가 달라집니다. man에 나온 메뉴얼에 따르면 아래와 같습니다.

 

 종료가 된 child의 경우, wait를 동작하게 하는 것은 system이 child에 관한 리소스를 해제할 수 있게 도와준다는 말이 나옵니다. 그렇지 않으면 Zombie가 된다고 언급하고 있습니다. 그러면 여기서 the resource는 무엇을 가리킬까요? man page의 Notes를 보면 대략적으로 유추할 수 있습니다.

 

 종료된 child에 대해서 wait를 perform을 하면, 리소스를 해제하고, 그렇지 않으면 해제하지 않고, zombie가 됩니다. zombie는 리소스를 해제하지 않았으니까, 소모할 거에요. 이 두 문장을 통해 유추를 해 보면, 소모하는 것은 slot in the process table입니다. 이는, 종료가 되었지만, 상태를 회수하지 않은 자식에 대한 정보를 담고 있는 레코드 하나를 의미합니다.

 

 

 그러면, 종료된 child의 상태를 wait나 waitpid로 회수를 했다면 어떻게 될까요? 이 때에는 system이 종료된 자식에 대한 리소스를 release 하는 것을 allow 합니다.


 해당 프로그램이 종료되면 어떻게 될까요? 그 프로세스는, wait를 호출해서, 종료 상태를 회수하게 됩니다. 

 

 

 다시 ps - au 명령어를 쳐 보면, STAT이 Z+인 것이 없다는 것을 알 수 있습니다.