Linux 시스템 프로그래밍 프로세스 (Linux 프로세스, fork () 함수, 좀비 프로세스, 고아 프로세스)

1. Linux 프로세스

1.1 프로세스 개념 :

  • 사용자의 관점에서 보면 프로세스는 실행중인 프로그램입니다.
  • 운영 체제 관점 : 운영 체제는 프로그램을 실행하며 프로그램의 실행 프로세스를 설명해야합니다.이 설명은 task_struct {} 구조로 설명되며 총칭하여 PCB라고합니다. 따라서 운영 체제의 경우 프로세스는 PCB (프로세스 제어 블록) 프로그램 제어 조각
  • 프로세스의 설명 정보에는 식별자 PID, 프로세스 상태, 우선 순위, 프로그램 카운터, 컨텍스트 데이터, 메모리 포인터, IO 상태 정보 및 계정 정보가 포함됩니다. 모두 예약을위한 운영 체제가 필요합니다.

1.2 프로세스 상태 :

/*
* The task state array is a strange "bitmap" of
* reasons to sleep. Thus "running" is zero, and
* you can test for combinations of others with
* simple bit tests.
*/
static const char * const task_state_array[] = {
    
    
"R (running)", /* 0 */
"S (sleeping)", /* 1 */
"D (disk sleep)", /* 2 */
"T (stopped)", /* 4 */
"t (tracing stop)", /* 8 */
"X (dead)", /* 16 */
"Z (zombie)", /* 32 */
};

2. fork () 함수

2.1 개요 :

fork () 함수를 사용하여 얻은 자식 프로세스는 부모 프로세스의 복사본입니다.
프로세스 컨텍스트 (프로세스 실행 활동의 전체 프로세스에 대한 정적 설명), 프로세스를 포함 하여 부모 프로세스로부터 전체 프로세스의 주소 공간을 상속합니다. 스택 및 열린 파일 설명자, 신호 제어 설정, 프로세스 우선 순위, 프로세스 그룹 번호 등 자식 프로세스에 고유 한 것은 프로세스 번호, 타이머 등입니다 (소량의 정보 만).

pid_t fork(void);

헤드 파일 :

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

풍모:

  • 기존 프로세스에서 새 프로세스를 만드는 데 사용되는 새 프로세스를 자식 프로세스라고하고 원래 프로세스를 부모 프로세스라고합니다.

반환 값 :

  • 성공 : 0은 자식 프로세스에서 반환되고 자식 프로세스 ID는 부모 프로세스에서 반환됩니다. pid_t는 부호없는 정수입니다.
  • 실패 : -1을 반환합니다.

코드 예 :

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
 
int main(int argc, char *argv[])
{
    
    
	pid_t pid;
	pid = fork();
	
	if( pid < 0 ){
    
    	// 没有创建成功
		perror("fork");
	}
	
	if(0 == pid){
    
     // 子进程
		while(1){
    
    
			printf("I am son\n");
			sleep(1);
		}
	}
	else if(pid > 0){
    
     // 父进程
		while(1){
    
    
			printf("I am father\n");
			sleep(1);
		}
	}
	
	return 0;
}

2.2 작동 결과 :

여기에 사진 설명 삽입

2.3 요약 :

  • 실행 결과를 통해 부모와 자식 프로세스가 각각 한 가지 작업을 수행하는 것을 볼 수 있습니다 (각각 문장이 인쇄 됨). 여기서는 코드가 하나만 있다는 것을 알 수 있습니다. 사실, fork ()
    이후에 두 개의 주소 공간이 독립적으로 실행되며 이는 두 개의 독립적 인 프로그램 (부모 및 자식 프로세스)이 실행되는 것과 약간 유사합니다. 자식 프로세스의 주소 공간에서 자식 프로세스는 fork () 함수 이후에 코드 실행을 시작합니다.
  • fork () 이후에는 부모 프로세스가 먼저 실행되는지 자식 프로세스가 먼저 실행되는지는 불확실합니다. 이것은 커널에서 사용하는 스케줄링 알고리즘에 따라 다릅니다.

3. 좀비 프로세스

프로세스는 fork를 사용하여 자식 프로세스를 생성합니다. 자식 프로세스가 종료되고 부모 프로세스가 자식 프로세스 정보를 얻기 위해 wait () 또는 waitpid ()를 호출하지 않으면 자식 프로세스 설명자는 여전히 시스템에 저장됩니다. 일종의 프로세스를 좀비 프로세스라고합니다.

Z 进程

3.1 코드는 좀비 프로세스를 시뮬레이션합니다.

#include <stdio.h>                                                                                                                                                                             
#include <stdlib.h>
#include <unistd.h>

int main()
{
    
    
  printf("输入一遍\n");
  pid_t ret = fork();
  if(ret > 0)
  {
    
    
    //parent    
    while(1)    
    {
    
        
    printf("I am parent! pid is : %d\n", getpid());    
    sleep(1);    
    }    
  }    
  else if(ret == 0)    
  {
    
        
    /child    
    int count = 0;    
    while(count<5)    
    {
    
        
      printf("I am child! pid is : %d, ppid: %d\n", getpid(), getppid());    
      count++;    
      sleep(2);    
    }    
    exit(0);    
  }    
  else    
  {
    
        
    printf("fork error\n");    
  }    
  sleep(1);    
  return 0;    
}

3.2 좀비 프로세스 결과 표시 :

여기에 사진 설명 삽입

3.3 좀비 프로세스 피해 :

자식 프로세스의 종료 상태는 항상 유지되며, 종료 상태 자체를 유지하려면 데이터 유지 관리가 필요하며 프로세스의 기본 정보에 속하며 저장됩니다 task_struct. 즉, Z 상태가 종료되지 않는 한 PCB는 항상 종료 정보를 유지해야합니다. 부모 프로세스가 재활용하지 않고 많은 자식 프로세스를 생성 造成内存资源的极大浪费하면 그 원인이됩니다 内存泄露.

4. 고아 프로세스

부모 프로세스가 일찍 종료되면 자식 프로세스를 "고아 프로세스"라고합니다. 상위 프로세스가 종료되면 하위 프로세스는 종료하려고 할 때 Z 상태가됩니다. 종료 정보를 수신하는 프로세스가 없기 때문에 하위 프로세스가되는 것을 방지하기 위해 고아 프로세스를 채택하고 초기화 프로세스 1 번에 의해 재활용해야합니다. 좀비 프로세스.

4.1 코드는 고아 프로세스를 시뮬레이션합니다.

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>

int main()
{
    
    
  pid_t ret = fork();
  if(ret < 0)
  {
    
    
    printf("创建进程失败!\n");
  }
  else if(ret > 0)
  {
    
    
    int count = 0;
    while(count++ < 5)
    {
    
    
      printf("我是父进程(id:%d)\n",getpid());
      sleep(2);
    }
    exit(0);
  }
  else
  {
    
    
    while(1)
    {
    
    
      printf("我是子进程(id:%d)\n",getpid());
      sleep(1);
    }
  }
  sleep(1);
  return 0;
}

4.2 고아 프로세스 결과 표시 :

여기에 사진 설명 삽입

4.3 요약 :

OS는이 상황을 고려하여 부모 프로세스가 종료되고 자식 프로세스가 여전히 실행 중일 때 (자식 프로세스를 고아 프로세스라고 함) 그림에 표시된대로 프로세스 시스템 No. 1과 같이 아버지를 다시 찾습니다.

프로세스 번호 1 (init) 확장 :

0 프로세스에 의해 생성되어 시스템 초기화 완료 시스템의 다른 모든 사용자 프로세스의 상위 프로세스입니다.
Linux의 모든 프로세스는 init 프로세스에 의해 생성되고 실행됩니다. 먼저 Linux 커널이 시작된 다음 사용자 공간에서 init 프로세스가 시작된 다음 다른 시스템 프로세스가 시작됩니다. 시스템 시작이 완료되면 init는 시스템의 다른 프로세스를 모니터링하는 데몬이됩니다.

추천

출처blog.csdn.net/weixin_45313447/article/details/114443655