좀비과정

Zombie process

유닉스, 유닉스 같은 컴퓨터 운영체제에서 좀비 프로세스소멸된 프로세스는 (이를 통해) 실행을 완료한 프로세스다.exit 시스템 호출)이지만 프로세스 표에는 여전히 "종료 상태"의 프로세스라는 항목이 있다.이는 하위 프로세스에서 발생하며, 상위 프로세스가 하위 프로세스의 종료 상태를 읽을 수 있도록 여전히 항목이 필요한 경우: 종료 상태를 다음 명령을 통해 읽으면wait 시스템 호출, 좀비의 항목이 프로세스 테이블에서 제거되고 "리핑"되었다고 한다.하위 프로세스는 리소스 테이블에서 제거되기 전에 항상 먼저 좀비가 된다.대부분의 경우 정상적인 시스템 작동에서 좀비는 부모에 의해 즉시 대기한 다음 시스템에 의해 수집된다. 좀비들이 장기간 머무르는 프로세스는 일반적으로 오류로 인해 자원 누출을 일으키지만, 이들이 점유하는 유일한 자원은 프로세스 테이블 항목인 프로세스 ID이다.null

좀비 과정이라는 용어는 언데드좀비의 일반적인 정의에서 유래되었다.이 용어의 은유에서 아동 과정은 "디디드"되었지만 아직 "리피드"되지는 않았다.또한, 일반적인 과정과 달리,kill명령은 좀비 과정에 영향을 주지 않는다.null

좀비 과정은 고아 과정과 혼동해서는안 된다:고아 과정은 여전히 실행 중이지만 부모가 죽은 과정이다.부모가 사망했을 때, 고아 아동 프로세스는 다음에 의해 채택된다.init(프로세스 ID 1)고아 과정이 죽으면 좀비 과정으로 남아 있지 않고 오히려 고아가 된다.wait에 의지하다.init그 결과는 좀비와 고아인 과정이 자동으로 수집될 것이다.null

개요

프로세스를 종료할 때exit, 그것과 관련된 모든 메모리와 자원은 다른 프로세스들에 의해 사용될 수 있도록 할당되지 않는다.그러나 프로세스 표의 프로세스 입력은 그대로 남아 있다.부모는 다음 작업을 실행하여 자녀의 종료 상태를 읽을 수 있다.wait 좀비가 제거되는 시스템 호출.wait 통화는 순차적 코드로 실행될 수 있지만, 일반적으로 부모가 아이가 사망할 때마다 받는 SIGCLDsignal핸들러에서 실행된다.null

좀비를 제거한 후 프로세스 식별자(PID)와 프로세스 테이블의 항목을 재사용할 수 있다.그러나 부모가 전화를 걸지 못할 경우wait좀비는 프로세스 테이블에 남겨져 자원 누출을 일으킬 것이다.예를 들어 부모가 다른 자식 프로세스를 만들 경우 동일한 PID가 할당되지 않도록 보장할 수 있는 경우(부모 프로세스가 이 자원을 계속 보유하기를 원하는 경우) 이는 바람직할 수 있다.(이 점에서 SUSv3 규격을 준수하는) 현대의 UNIX와 유사한 시스템에서는 다음과 같은 특별한 경우를 적용한다:부모가 취급자를 다음과 같이 설정하여 SIGCHLD를 명시적으로 무시하는 경우SIG_IGN(기본적으로 신호를 단순히 무시하는 것보다 더 높음) 또는 다음이 있는 경우SA_NOCLDWAIT플래그가 설정되고, 모든 아동 퇴학 상태 정보가 삭제되며, 좀비 프로세스가 남지 않는다.[1]

Unix의 출력에서 좀비를 식별할 수 있음ps "의 존재로 명령하다.Z"[2]STAT" 열의 ".단기간 이상 존재하는 좀비들은 전형적으로 부모 프로그램에 버그가 있거나, 아이를 낳지 않는 흔치 않은 결정(예시 참조)을 나타낸다.상위 프로그램이 더 이상 실행되지 않는 경우, 좀비 프로세스는 일반적으로 운영 체제에 버그를 나타낸다.다른 자원 유출과 마찬가지로, 몇몇 좀비들의 존재는 그 자체로 걱정스러운 것이 아니라, 무거운 짐 속에서 심각해질 문제를 나타낼 수도 있다.좀비 프로세스에 할당된 메모리가 없기 때문에(시스템 메모리 사용량은 프로세스 테이블 입력 자체에 대한 것임) 많은 좀비들의 주요 관심사는 메모리가 소진되는 것이 아니라 프로세스 테이블 항목, 즉 ID 번호를 구체적으로 처리하는 것이다.null

시스템에서 좀비를 제거하려면 를 사용하여 SIGCLD 신호를 수동으로 부모에 전송할 수 있다.kill명령하다만약 부모 과정이 여전히 좀비 수확을 거부한다면, 그리고 부모 과정을 종료하는 것이 괜찮다면, 다음 단계는 부모 과정을 제거하는 것이다.공정이 부모를 잃으면init새로운 부모가 된다.nullinit정기적으로 를 실행하다.wait어떤 좀비라도 거둬들이라는 시스템 호출init부모로서null

특정(특정) 순서에 따라 특정 자식 프로세스를 동시에 대기하면 좀비가 위에서 언급한 "단기간"보다 더 오래 존재할 수 있다.그것은 반드시 프로그램 버그는 아니다.null

#include <sys/기다려라.h> #include <stdio.h> #include <stdlib.h> #include <유니스트드>.h>  인트로 본래의(공허하게 하다) {     pid_t 새끼들[10];     인트로 i;      을 위해 (i = 9; i >= 0; --i) {         새끼들[i] = 포크를 갈다();         만일 (새끼들[i] == 0) {             활자화하다("Child%d"\n", i);             잠을 자다(i+1);             _beakes(0);         }     }      을 위해 (i = 9; i >= 0; --i) {         활자화하다("parent%d"\n", i);         미온적인 태도를 취하다(새끼들[i], NULL, 0);     }      돌아오다 0; } 

출력

parent9 child3 child4 child4 child2 child2 child1 child6 child0 child7 child8 child9 // 여기서 parent8 parent8 parent7 parent6 parent4 parent3 parent2 parent1 parent0

설명

첫 번째 루프에서 원본(상위) 프로세스는 10개의 자체 복사본을 포크로 처리한다.이 아이들은 각각 메시지를 인쇄하고, 잠을 자고, 퇴장하는 과정(포크()가 0을 반환한 사실에 의해 감지됨)을 처리한다.모든 아이들은 본질적으로 동시에 만들어지기 때문에(부모는 루프를 거의 하지 않기 때문에), 각 아이들이 처음으로 일정을 잡을 때 다소 무작위적이기 때문에, 따라서 그들의 메시지의 스크램블한 순서가 된다.null

루프가 진행되는 동안 하위 프로세스 ID 배열이 구축된다.11개의 모든 프로세스에는 pids[] 배열의 복사본이 있지만, 부모에서만 완성된다. 각 자식에는 숫자가 낮은 PID가 없고, 자신의 PID를 위한 0이 있다. (부모 프로세스만이 실제로 이 배열을 사용하기 때문에 이것이 정말로 중요한 것은 아니다.)null

두 번째 루프는 부모 프로세스에서만 실행되며(이 시점 이전에 모든 아이가 빠져나갔기 때문에), 각 아이가 종료될 때까지 기다린다.먼저 10초간 잠을 잔 아이를 기다린다. 다른 아이들은 모두 퇴사한 지 오래돼 메시지(첫 번째 메시지 제외)가 모두 연달아 나타난다.단일 공정에서 루프에 의해 구동되기 때문에 여기서는 무작위 오더의 가능성이 없다.첫 번째 부모 메시지는 실제로 자식 메시지 앞에 나타났다는 점에 유의하십시오. 부모는 자식 프로세스가 시작되기 전에 두 번째 루프로 계속 이동할 수 있었다.이것은 다시 한번 프로세스 스케줄러의 무작위 행동일 뿐이다 - "parent9" 메시지는 "parent8" 이전의 순서의 어느 곳에도 나타날 수 있었다.null

Child0에서 Child8까지 Child0은 그들이 떠난 시간과 부모가 그들에게 미온적인()을 한 시간 사이에 이 상태에서 1초 이상을 보낸다.부모는 차일드9이 퇴장하기 전에 이미 차일드9을 기다리고 있었고, 그래서 한 과정은 본질적으로 좀비로써 시간을 보내지 않았다.[3]

참고 항목

참조

  1. ^ "wait(2) Man Page". Linux Programmer's Manual.
  2. ^ "Zombies(5) - UNIX System V (Concepts)". The Collider Detector at Fermilab.
  3. ^ "Linux - Can someone please explain how this works?fork(),sleep()".

외부 링크