소켓서버를 개발을 하게 되면서 내가 개발한 프로그램이 kill 명령어로도 죽일 수 없는 좀비상태가 되는 현상이 계속 발생하였다.
이 문제를 해결하기 위해 GPT를 사용하여 좀비 프로세스 원인과 확인방법, 해결방법을 정리해 보았다.
1. 좀비 프로세스란?
좀비 프로세스는 프로세스가 종료되었으나 부모 프로세스가 자식의 종료 상태를 수집하지 않아 프로세스 테이블에 남아있는 상태를 의미한다.
좀비 프로세스는 시스템 자원을 소비하지는 않지만, 너무 많이 쌓이면 시스템 성능에 영향을 줄 수 있다.
1-1. 좀비 프로세스 발생 원인
- 부모 프로세스가 자식 프로세스의 종료를 기다리지 않음: 부모 프로세스가 wait() 또는 waitpid()를 호출하지 않아 자식 프로세스의 종료 상태를 수집하지 못할 때 발생한다.
- 자식 프로세스가 먼저 종료되는 경우: 자식 프로세스가 부모보다 먼저 종료되면 부모가 종료 상태를 수집할 때까지 좀비 상태로 남는다.
1-2. 좀비 프로세스 문제 해결 방법
1. wait() 또는 waitpid() 사용
부모 프로세스에서 wait() 또는 waitpid()를 호출하여 자식 프로세스의 종료 상태를 수집할 수 있다.
int pid = fork();
if (pid == 0) {
// 자식 프로세스 코드
exit(0);
} else {
// 부모 프로세스 코드
wait(NULL); // 자식 프로세스의 종료 상태 수집
}
2. SIGCHLD 시그널 핸들러 설정
시그널 핸들러(signal handler)는 프로세스가 특정 시그널(signal)을 받을 때 호출되는 사용자 정의 함수이다
시그널은 프로세스 간 통신이나 프로세스와 커널 간의 비동기식 이벤트 전달을 위한 메커니즘으로, 예를 들어 키보드 입력, 프로세스 종료, 알람 타이머 등과 같은 이벤트가 발생했을 때 프로세스에 특정한 시그널이 전송된다.
- SIGCHLD : 자식 프로세스가 종료될 때 부모 프로세스에 보내지는 시그널이다.
SIGCHLD 시그널 핸들러를 설정하면 자식 프로세스가 종료될 때 부모 프로세스가 자동으로 종료 상태를 수집할 수 있다.
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
void handle_sigchld(int sig) {
while (waitpid(-1, NULL, WNOHANG) > 0);
}
int main() {
signal(SIGCHLD, handle_sigchld); // SIGCHLD 시그널 핸들러 설정
if (fork() == 0) {
// 자식 프로세스 코드
exit(0);
}
// 부모 프로세스가 다른 작업 수행
while (1) {
sleep(1);
}
}
2. 좀비 프로세스 확인 방법
1) ps 명령어 사용
ps 명령어를 사용하여 프로세스의 상태를 확인할 수 있다.
좀비프로세스는 프로세스의 상태가 Z로 표시된다.
ps aux | grep Z
- STAT 열에 Z가 표시된 프로세스가 좀비 상태이다.
- 예:
user 12345 0.0 0.0 0 0 ? Z 12:34 0:00 [process_name] <defunct>
2) top 명령어 사용
top 명령어는 시스템의 현재 프로세스를 실시간으로 보여준다
top
- STAT 열에서 Z로 표시된 프로세스가 좀비 상태이다
3. 좀비 프로세스 해결 방법
1) 부모 프로세스 종료
좀비 프로세스의 부모 프로세스를 종료하면, 부모 프로세스가 자식의 종료 상태를 수집하여 좀비 프로세스가 사라진다.
- 좀비 프로세스의 부모 PID 확인:
ps -o ppid= -p <Zombie PID>
- 부모 프로세스 종료:
kill -9 <부모 PID>
2) 시스템 재부팅
시스템을 재부팅하면 모든 좀비 프로세스가 제거된다.
sudo reboot
4. 주의사항
- 좀비 프로세스가 하나 또는 소수라면 시스템에 큰 영향을 주지 않는다.
- 시스템에 너무 많은 좀비 프로세스가 쌓이면 시스템 리소스를 낭비할 수 있으므로 주기적으로 확인하는 것이 좋다.
'OS > Unix' 카테고리의 다른 글
[UNIX] 네트워크 진단도구 Ping (0) | 2025.01.19 |
---|---|
[UNIX] Unix에서 프로세스 관리 : 프로세스 확인과 종료 방법 (0) | 2025.01.15 |
[UNIX] crontab 스캐줄러 (0) | 2023.04.18 |
[UNIX] 네트워크 연결 확인 - netstat / + port,socket (0) | 2023.02.11 |
[UNIX] 디스크 용량 확인 - df, du (0) | 2023.02.11 |