본문 바로가기
ChatGPT/프로...Linux

프로세스 <defunct> 처리(SIGCHLD 처리)

by 크크다스 2025. 4. 2.
반응형
나의 말:
<defunct>
ChatGPT의 말:

Linux에서 <defunct>로 표시되는 프로세스는 흔히 '좀비 프로세스'라고 불리며, 이는 자식 프로세스가 종료되었지만 부모 프로세스가 아직 해당 자식의 종료 상태를 수집하지 않은 상태를 의미합니다. 이러한 좀비 프로세스는 시스템의 프로세스 테이블에 남아 있으며, 일반적인 방법으로는 제거할 수 없습니다.Wikipedia

좀비 프로세스의 특징:

  • 자원 사용: 좀비 프로세스는 실행 중인 프로세스가 아니므로 CPU나 메모리와 같은 시스템 자원을 소비하지 않습니다. 그러나 프로세스 테이블 엔트리를 차지하므로, 다수의 좀비 프로세스가 존재하면 새로운 프로세스 생성을 방해할 수 있습니다.

  • 식별: ps aux 명령어를 실행했을 때, STAT 열에 Z로 표시되거나 COMMAND 열에 <defunct>로 나타나는 프로세스가 좀비 프로세스입니다.Baeldung+2LinkedIn+2Server Fault+2

좀비 프로세스 제거 방법:

  1. 부모 프로세스 확인: 좀비 프로세스의 부모 프로세스를 찾아야 합니다. 이를 위해 다음 명령어를 사용합니다:

    bash
    ps -ef | grep defunct

출력 결과에서 좀비 프로세스의 PPID(부모 프로세스 ID)를 확인합니다.

  1. 부모 프로세스에 시그널 전송: 부모 프로세스가 자식의 종료 상태를 수집하도록 SIGCHLD 시그널을 보낼 수 있습니다:Wikipedia, l'enciclopedia libera+7Wikipedia+7Wikipedia, la enciclopedia libre+7

    bash
    kill -s SIGCHLD [부모 프로세스 ID]

이 명령어는 부모 프로세스에게 자식 프로세스의 종료 상태를 확인하도록 요청합니다.

  1. 부모 프로세스 종료: 만약 위의 방법으로도 좀비 프로세스가 제거되지 않는다면, 부모 프로세스를 종료하는 방법이 있습니다:

    bash
    kill -9 [부모 프로세스 ID]

부모 프로세스를 종료하면 해당 좀비 프로세스는 init 프로세스에 의해 수거되어 제거됩니다.

주의사항: 좀비 프로세스는 시스템 자원을 거의 소비하지 않으므로, 소수의 좀비 프로세스는 시스템 성능에 큰 영향을 미치지 않습니다. 그러나 다수의 좀비 프로세스가 존재하면 시스템 자원 관리에 문제가 발생할 수 있으므로, 이러한 상황을 방지하기 위해 부모 프로세스의 종료 상태를 적절히 관리하는 것이 중요합니다.

참고 자료:

위의 자료들은 좀비 프로세스의 개념과 처리 방법에 대해 자세히 설명하고 있으므로, 추가적인 이해를 위해 참고하시기 바랍니다.

나의 말:
SIGCHLD 처리하는 c 코드
ChatGPT의 말:

Linux에서 SIGCHLD 시그널은 자식 프로세스가 종료될 때 부모 프로세스에게 전달되어, 부모가 자식의 종료 상태를 확인하고 리소스를 정리할 수 있도록 합니다. 이 시그널을 처리하지 않으면 좀비 프로세스가 발생할 수 있으므로, 적절한 처리가 필요합니다.

SIGCHLD 시그널 처리 예제:

c
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <signal.h> #include <sys/wait.h> void handle_sigchld(int sig) { (void)sig; // Unused parameter int saved_errno = errno; // Preserve errno while (waitpid(-1, NULL, WNOHANG) > 0); errno = saved_errno; // Restore errno } int main() { struct sigaction sa; sa.sa_handler = &handle_sigchld; sigemptyset(&sa.sa_mask); sa.sa_flags = SA_RESTART | SA_NOCLDSTOP; if (sigaction(SIGCHLD, &sa, 0) == -1) { perror("sigaction"); exit(EXIT_FAILURE); } pid_t pid = fork(); if (pid == -1) { perror("fork"); exit(EXIT_FAILURE); } else if (pid == 0) { // 자식 프로세스 코드 printf("자식 프로세스 실행 중...\n"); sleep(2); printf("자식 프로세스 종료.\n"); exit(EXIT_SUCCESS); } else { // 부모 프로세스 코드 printf("부모 프로세스: 자식 프로세스 생성 완료.\n"); // 부모 프로세스는 여기서 다른 작업을 수행할 수 있음 sleep(5); // 예시를 위한 대기 } return 0; }

코드 설명:

  1. 시그널 핸들러 정의 (handle_sigchld):

    • SIGCHLD 시그널을 처리하기 위한 핸들러를 정의합니다.일상의 정리+1컴영의 기록지+1

    • waitpid 함수를 사용하여 종료된 자식 프로세스의 상태를 비동기적으로 수집합니다. WNOHANG 옵션을 사용하여 블로킹을 방지합니다.

    • errno 값을 보존하고 복원하여, 시그널 핸들러 내에서의 시스템 호출이 외부 코드에 영향을 주지 않도록 합니다.일상의 정리

  2. 시그널 핸들러 등록:

    • sigaction 구조체를 초기화하고, SIGCHLD 시그널에 대한 핸들러를 등록합니다.

    • SA_RESTART 플래그는 시그널 핸들러 실행 후 인터럽트된 시스템 호출을 자동으로 재시작하도록 합니다.일상의 정리

    • SA_NOCLDSTOP 플래그는 자식 프로세스가 정지되었을 때 SIGCHLD 시그널이 발생하지 않도록 합니다.

  3. 자식 프로세스 생성 및 실행:

    • fork 함수를 호출하여 자식 프로세스를 생성합니다.

    • 자식 프로세스는 간단한 메시지를 출력하고 종료합니다.

  4. 부모 프로세스의 동작:

    • 부모 프로세스는 자식 프로세스의 종료를 기다리지 않고, 다른 작업을 수행할 수 있습니다.

    • 자식 프로세스가 종료되면 SIGCHLD 시그널이 발생하고, 등록된 핸들러가 호출되어 자식의 종료 상태를 수집합니다.

주의사항:

  • 시그널 핸들러 내에서 호출되는 함수는 재진입 가능(reentrant)해야 하며, 시그널 안전(signal-safe)해야 합니다.

  • waitpid 호출 시 WNOHANG 옵션을 사용하여 핸들러가 블로킹되지 않도록 해야 합니다.규동 프로그래밍(KyooDong)+1일상의 정리+1

참고 자료:

위의 자료들은 SIGCHLD 시그널 처리와 관련된 추가적인 정보를 제공하므로 참고하시기 바랍니다.

반응형