[Linux] RHEL 좀비 프로세스 원인과 해결방법

Linux 서버를 운영을 하다보면 여러가지 상황이 많이 발생하게 된다.

그중에 오늘은 좀비 프로세스에 대해서 알아볼려고 합니다.

리눅스 좀비프로세스에 대한 원인과 해결방법

좀비 프로세스란?

좀비 프로세스는 부모 프로세스가 아직 그 종료 상태를 회수하지 않은 상태에서 이미 실행을 종료한 프로세스를 의미합니다.

프로세스가 종료되면 커널은 그 프로세스의 종료 상태를 저장하고 프로세스를 좀비 상태로 만듭니다.

이후 부모 프로세스가 child의 종료 상태를 회수하면 좀비 프로세스는 완전히 사라집니다.

이 과정을 ‘회수(reaping)’라고 합니다. 그러나 부모 프로세스가 자식 프로세스의 종료 상태를 회수하지 않으면,

종료된 자식 프로세스는 좀비 상태로 계속 남아있게 됩니다.

이런 프로세스는 시스템 자원을 소비하지는 않지만, 프로세스 테이블에는 계속 남아있게 되어 프로세스 ID를 소비하게 됩니다. 따라서, 좀비 프로세스를 방지하기 위해 부모 프로세스는 항상 자식 프로세스의 종료 상태를 체크하고 회수해야 합니다. 이를 위해 C 언어에서는 wait() 또는 waitpid() 함수를 주로 사용합니다.


좀비 프로세스를 생성 후 테스트 해보자..

Linux에서 간단하게 zombie.c 등 이름을 선정해서

#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>

int main(){
    pid_t child_pid;

    // 부모 프로세스에서 자식 프로세스 생성
    child_pid = fork();

    if(child_pid > 0) {
        // 부모 프로세스는 잠시 동안 sleep 상태에 들어감
        sleep(50);
    }
    else {
	// 자식 프로세스는 즉시 종료됨
        exit(0);
    }
    return 0;
}

zombie.c를 만든 후 컴파일 진행 gcc 패키지가 없을 경우 여기를 클릭하여 설치 진행

좀비프로세스 파일 컴파일 진행

zombie를 백그라운드 실행을 시킨다음 ps 명령어를 통해 확인

sleep 50초를 걸어두었기 때문에 정상 실행 시켜도 백그라운드 전환 후 확인해야 합니다.

좀비 프로세스 백그라운드 실행 후 프로세스 확인

현재 상태를 보면, 프로세스 zombi의 부모 프로세스 ID는 29925입니다.

이 프로세스를 종료하면 zombi 프로세스는 init 프로세스의 자식이 되어 종료 상태가 회수되고, zombi 프로세스는 시스템에서 제거됩니다.

# ps -ef | grep defunct
kill -9 [PID]
좀비프로세스 제거하기

이 방법은 부모 프로세스가 중요한 작업을 수행하고 있지 않은 경우에만 사용해야 합니다. 부모 프로세스가 중요한 작업을 수행하고 있다면, 부모 프로세스 코드를 수정하여 종료된 자식 프로세스의 상태를 적절히 회수하도록 해야 합니다. 만약 부모 프로세스가 이미 종료되었거나 kill 명령이 실패한 경우, 시스템을 재부팅하는 것이 좀비 프로세스를 제거하는 가장 확실한 방법입니다.


좀비 프로세스를 제거 주의 사항

  • 좀비 프로세스를 제거하는 가장 일반적인 방법은 부모 프로세스를 종료하는 것입니다. 이 방법은 부모 프로세스가 중요한 작업을 수행하고 있지 않을 때만 사용해야 합니다. 부모 프로세스가 중요한 작업을 수행하고 있다면, 이 방법을 사용하면 그 작업이 중단되고 시스템에 문제가 발생할 수 있습니다.
  • 시스템을 재부팅하면 모든 프로세스가 종료되므로 좀비 프로세스도 제거됩니다. 시스템에 지장을 주지 않는 상황에서만 사용해야 합니다. 또한, 시스템을 재부팅하면 다른 사용자의 작업이 중단될 수 있으므로 주의가 필요합니다.
  • 좀비 프로세스가 많이 생성되면 시스템의 프로세스 ID가 소진될 수 있습니다. 이는 신규 프로세스 생성을 방해하므로, 좀비 프로세스가 많이 생성되지 않도록 주의해야 합니다.

By Low ahn

리눅스를 처음 접하시는 분들은 위한 다양한 리눅스 정보를 공유합니다.

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다