리눅스 시스템---좀비 프로세스, 고아 프로세스

구더취안:개인 홈페이지

개인 칼럼:"Linux 운영 체제"  "C/C++"  "LeedCode 질문 작성"

키보드도 안좋고 연봉도 100만!

       이전 글블로그에 대한 학습을 ​​통해 프로세스에 대한 기본 지식을 간략하게 이해했습니다. 오늘은 두 가지 특별한 내용을 알아보겠습니다. .프로세스, 좀비 프로세스 및 고아 프로세스.


1. 좀비 프로세스

1. 관련 개념

       좀비 프로세스는 실행이 완료되었지만 프로세스 테이블에 여전히 존재하는 프로세스입니다. 즉, 프로세스가 종료되면 해당 상위 프로세스는 하위 프로세스의 종료 상태 정보를 수집하기 위해 즉시 wait 또는 waitpid를 호출하지 않으므로 하위 프로세스가 종료되더라도 여전히 프로세스 테이블에 자리를 차지하게 됩니다. 좀비 프로세스가 형성됩니다. 좀비 프로세스는 실제로 죽어가는 상태(Z-좀비)라고도 불리는 비교적 특별한 상태입니다. 프로세스의 종료 상태는 유지되어야 합니다. 왜냐하면 프로세스는 자신에게 주어진 작업을 내가 얼마나 잘 수행했는지를 관심 있는 프로세스(부모 프로세스)에 알려야 하기 때문입니다. 실제 프로그래밍 과정에서는 리소스가 해제되지 않은 좀비 프로세스의 문제에 주의를 기울여야 합니다. ps 명령을 grep 'Z'와 함께 사용하면 상태 Z의 모든 프로세스, 즉 좀비 프로세스를 찾을 수 있습니다.

2. 좀비 상태

        좀비는 상대적으로 특별한 상태입니다. 프로세스가 종료되고 상위 프로세스(나중에 설명되는 wait() 시스템 호출 사용)가 하위 프로세스 종료의 반환 코드를 읽지 않으면 좀비(좀비) 프로세스가 생성됩니다. 좀비 프로세스는 종료된 상태로 프로세스 테이블에 남아 있으며 상위 프로세스가 종료 상태 코드를 읽기를 기다리고 있습니다. 따라서 자식 프로세스가 종료되는 한 부모 프로세스는 계속 실행되지만 부모 프로세스는 자식 프로세스 상태를 읽지 않고 자식 프로세스는 Z 상태에 들어갑니다.

3. 좀비 프로세스 생성

30초 동안 지속되는 좀비 프로세스를 생성하는 예를 들어보겠습니다.

#include <stdio.h>
#include <stdlib.h>
int main()
{
     pid_t id = fork();
     if(id < 0)
    {
         perror("fork");
         return 1;
    }
    else if(id > 0)
    { //parent
         printf("parent[%d] is sleeping...\n", getpid());
         sleep(30);
    }
    else
    {
         printf("child[%d] is begin Z...\n", getpid());
         sleep(5);
         exit(EXIT_SUCCESS);
    }
     return 0;
}

다른 터미널에서 컴파일하고 모니터링합니다.

테스트 시작:

결과를 확인하세요: 

참고: ptrace 시스템 호출은 프로세스 실행을 추적합니다. 관심이 있다면 연구해 보세요.

4. 좀비 프로세스의 피해

       1. 프로세스의 종료 상태는 유지되어야 합니다. 왜냐하면 프로세스는 자신이 나에게 준 작업을 어떻게 수행했는지 관심 있는 프로세스(부모 프로세스)에게 알려야 하기 때문입니다. 하지만 상위프로세스가 읽지 않으면 하위 프로세스는 항상 Z 상태가 됩니다?

       예!

       2. 종료상태를 유지하는 것 자체가 데이터 유지관리가 필요하고, 프로세스의 기본정보이기도 하므로 task_struct(PCB)에 저장됩니다.즉, Z 상태는 종료되지 않으며 PCB는 항상 유지 관리가 필요합니다?

       예!

메모리 리소스 낭비가 발생합니다?

       네, 데이터 구조 객체 자체가 메모리를 차지하기 때문에 C에서 구조 변수(객체)를 정의하여 메모리 어딘가에 공간을 여는 것을 생각해 보세요!

       4.内存泄漏?

       예!

5. 좀비 프로세스를 피하는 방법

       1.wait() 또는 waitpid() 함수 사용: 상위 프로세스에서 wait() 또는 waitpid() 함수 호출 and wait 하위 프로세스가 종료되고 상태 코드를 반환합니다. 이는 하위 프로세스가 종료된 후 해당 리소스가 정상적으로 재활용될 수 있도록 하고 좀비 프로세스 생성을 방지합니다.

       2.신호 처리기 프로그램 사용: 상위 프로세스에 SIGCHLD 신호 처리기를 등록합니다. 하위 프로세스가 끝나면 이를 알립니다. parent 프로세스는 이 신호를 보내고, 상위 프로세스는 신호 처리기에서 wait() 또는 waitpid() 함수를 호출하여 하위 프로세스의 자원을 회수할 수 있습니다.

       3.fork() 두 번: 첫 번째 포크의 하위 프로세스는 포크가 완료된 직후에 종료되므로 두 번째 포크는 획득한 하위 프로세스에는 더 이상 아버지가 없습니다. 조상 init 프로세스에 의해 자동으로 채택됩니다. Init는 리소스를 해제하여 "좀비"가 생성되지 않도록 합니다.


2. 고아 프로세스

1. 관련 개념

질문: 상위 프로세스가 일찍 종료되고 하위 프로세스가 나중에 종료되어 Z에 들어가면 어떻게 해야 합니까?

       상위 프로세스가 먼저 종료되고, 하위 프로세스를 "고아 프로세스"라고 합니다. 고아 프로세스는 init 프로세스 1번에 의해 채택됩니다. 물론 init 프로세스에 의해 재활용됩니다. a>

2. 고아 프로세스 생성

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main()
{
     pid_t id = fork();
     if(id < 0)
    {
         perror("fork");
         return 1;
    }
     else if(id == 0)
    {//child
         printf("I am child, pid : %d\n", getpid());
         sleep(10);
    }
    else
    {//parent
         printf("I am parent, pid: %d\n", getpid());
         sleep(3);
         exit(0);
     }
     return 0;
}

       구체적인 구현은 위와 동일합니다!

3. 고아 프로세스의 피해

       Orphan 프로세스는 상위 프로세스가 없는 프로세스입니다. Orphan 프로세스의 중요한 작업은 init 프로세스에 있습니다. init 프로세스는 민사국과 같으며 orphan 프로세스의 여파를 처리하는 역할을 담당합니다. 고아 프로세스가 나타날 때마다 커널은 고아 프로세스의 상위 프로세스를 init로 설정하고 init 프로세스는 종료된 하위 프로세스를 주기적으로 wait()합니다. 이러한 방식으로 고아 프로세스가 수명 주기를 비참하게 종료하면 init 프로세스가 당과 정부를 대신하여 모든 여파를 처리합니다.

       따라서 고아 프로세스에는 아무런 해가 없습니다.


3. 처리 우선순위

1. 관련 개념

       CPU 자원이 할당되는 순서는 프로세스의 우선순위를 나타냅니다.

       우선순위가 높은 프로세스는 우선순위 실행 권한을 갖습니다. 프로세스 우선순위 구성은 멀티태스킹 환경의 Linux에 매우 유용하며 시스템 성능을 향상시킬 수 있습니다.

       지정된 CPU에서 프로세스를 실행할 수도 있는데, 이렇게 중요하지 않은 프로세스를 특정 CPU에 배치하면 시스템 전체의 성능을 크게 향상시킬 수 있습니다.

2. 시스템 프로세스 보기

Linux 또는 Unix 시스템에서 ps-l 명령을 사용하면 다음과 유사한 내용이 출력됩니다.

다음과 같은 몇 가지 중요한 정보를 쉽게 확인할 수 있습니다.

       UID: 실행자의 신원을 나타냅니다.

       PID: 이 프로세스의 코드명을 나타냅니다.

       PPID: 이 프로세스가 파생된 프로세스, 즉 상위 프로세스의 코드명을 나타냅니다.

       PRI: 해당 프로세스가 실행될 수 있는 우선순위를 나타내며, 값이 작을수록 더 일찍 실행됩니다.

       Nl: 이 프로세스의 좋은 가치를 나타냅니다.

3.PRI 및 NI

       PRI는 프로세스의 우선순위, 즉 일반 용어로 CPU에서 프로그램이 실행되는 순서를 나타내는 것으로 비교적 이해하기 쉽습니다. 이 값이 작을수록 프로세스의 우선순위가 높아집니다.
       NI는 프로세스가 실행될 수 있는 우선순위의 수정된 값을 나타내는 우리가 말하는 Nice 값입니다.
 
       PRI 값이 작을수록 실행 속도가 빨라지며 nice 값을 추가하면 PRI는 다음과 같이 됩니다.
                        
                   PR1(신규)=PR1(기존)+-좋음
 
       이처럼 nice 값이 음수일 때 프로그램의 우선순위 값은 작아지는데, 즉 우선순위가 높아질수록 실행 속도가 빨라지므로 Linux에서 프로세스 우선순위를 조정한다는 것은 Process nice를 조정한다는 뜻이다. 값.
 
       nice의 값 범위는 -20부터 19까지이며 총 40개의 레벨이 있습니다.

4.PRI 대 NI

       프로세스의 좋은 값은 프로세스의 우선순위가 아니며 동일한 개념은 아니지만 프로세스의 좋은 값은 프로세스의 우선순위 변경에 영향을 미친다는 점을 강조해야 합니다.

       nice값은 프로세스 우선순위의 수정된 데이터임을 이해할 수 있다.


결론:Linux 시스템에서 프로세스의 2차 공유는 여기서 끝납니다. 데모 없이 작업을 연습할 수 있습니다. 이 문서의 공유가 모든 사람에게 도움이 되기를 바랍니다. 연구가 도움이 되었습니다. 질문이 있으시면 댓글란에 메시지를 남겨주세요~~~ 

추천

출처blog.csdn.net/m0_71746526/article/details/134635191