Linux 시스템 프로그래밍 35 프로세스 제어-초기화 프로세스 및 좀비 프로세스

다음 프로그램, 즉 fork ()는 소수 변경 사항을 찾습니다.

실험 1 부모 프로세스는 잠을 자지 않고 201 자식은 수면을 처리합니다.

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


#define LEFT 200
#define RIGHT 250

int main(void)
{
	int i,j,mark;
	pid_t pid;
	
	for(i = LEFT; i <= RIGHT; i++)
	{
		pid = fork();
		if(pid < 0)
		{
			fprintf(stderr,"fork() failed!\n");
			exit(1);
		}
		else if(pid == 0)//child
		{
			mark = 1;
			for(j = 2; j < i/2; j++)
			{
				if(i % j ==0)
					{
						mark = 0;
						break;
					}
			
			}

			if(mark)
				printf("%d is a primer\n",i);

			sleep(1000);
			exit(0);//!!!
		}
		
	}
	
	exit(0);
}

변경 : 각 하위 프로세스가 종료되기 전에 1000 초 동안 휴면합니다.이 경우 상위 프로세스가 먼저 종료되고 201 하위 프로세스가 종료 된 후에 종료해야합니다. 이 경우 부모 프로세스는 201 개의 자식 프로세스를 생성 한 후 바로 exit ()되고 자식 프로세스는 작업을 마친 후 휴면 상태가됩니다.

ps axf 프로세스 상태보기 :

mhr@ubuntu:~/Desktop/xitongbiancheng/test$ ps axf
15800 pts/2    S      0:00          \_ ./a.out
 15801 pts/2    S      0:00          \_ ./a.out
 15802 pts/2    S      0:00          \_ ./a.out
 15803 pts/2    S      0:00          \_ ./a.out
 15804 pts/2    S      0:00          \_ ./a.out
 15805 pts/2    S      0:00          \_ ./a.out
 15806 pts/2    S      0:00          \_ ./a.out
 15807 pts/2    S      0:00          \_ ./a.out
 15808 pts/2    S      0:00          \_ ./a.out
 15809 pts/2    S      0:00          \_ ./a.out
 15810 pts/2    S      0:00          \_ ./a.out
 15811 pts/2    S      0:00          \_ ./a.out
 15812 pts/2    S      0:00          \_ ./a.out
 15813 pts/2    S      0:00          \_ ./a.out
 15814 pts/2    S      0:00          \_ ./a.out
 15815 pts/2    S      0:00          \_ ./a.out
 15816 pts/2    S      0:00          \_ ./a.out
 15817 pts/2    S      0:00          \_ ./a.out
 15818 pts/2    S      0:00          \_ ./a.out
 15819 pts/2    S      0:00          \_ ./a.out
 15820 pts/2    S      0:00          \_ ./a.out
...
...
...

여기에 사진 설명 삽입

모든 201 하위 프로세스가 최상위 그리드에 의해 작성되었음을 알 수 있으므로 201 프로세스의 상위 프로세스가 init 프로세스입니다.

부모 프로세스가 종료 된 모든 프로세스에 대해 부모 프로세스가 init 프로세스로 변경되는 경우 이러한 프로세스를 init 프로세스에서 채택한 프로세스라고합니다. 작업 프로세스는 대략 다음과 같습니다. 프로세스 A가 종료되면 커널은 다른 모든 활성 프로세스 BCD 등을 확인하여 이러한 활성 프로세스가 프로세스 A를 종료하는 자식 프로세스인지 여부를 확인합니다. 활성 프로세스 프로세스가 1로 변경됩니다 (초기화 프로세스의 ID는 1 임).이 접근 방식은 모든 프로세스가 상위 프로세스를 갖도록합니다.

실험 2 부모 프로세스는 잠자고, 자식 프로세스는 잠들지 않습니다.

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


#define LEFT 200
#define RIGHT 250

int main(void)
{
	int i,j,mark;
	pid_t pid;
	
	for(i = LEFT; i <= RIGHT; i++)
	{
		pid = fork();
		if(pid < 0)
		{
			fprintf(stderr,"fork() failed!\n");
			exit(1);
		}
		else if(pid == 0)//child
		{
			mark = 1;
			for(j = 2; j < i/2; j++)
			{
				if(i % j ==0)
					{
						mark = 0;
						break;
					}
			
			}

			if(mark)
				printf("%d is a primer\n",i);

			
			exit(0);//!!!
		}
		
	}
	
	sleep(1000);
	exit(0);
}


mhr@ubuntu:~/Desktop/xitongbiancheng/test$ ps axf
 \_ zeitgeist-datahub
  2824 ?        Sl     0:37          \_ /usr/bin/python /usr/bin/terminator
  2836 ?        S      0:00          |   \_ gnome-pty-helper
  2837 pts/0    Ss     0:01          |   \_ /bin/bash
 16001 pts/0    R+     0:00          |   |   \_ ps axf
  2858 pts/2    Ss     0:00          |   \_ /bin/bash
 15944 pts/2    S+     0:00          |       \_ ./a.out
 15945 pts/2    Z+     0:00          |           \_ [a.out] <defunct>
 15946 pts/2    Z+     0:00          |           \_ [a.out] <defunct>
 15947 pts/2    Z+     0:00          |           \_ [a.out] <defunct>
 15948 pts/2    Z+     0:00          |           \_ [a.out] <defunct>
 15949 pts/2    Z+     0:00          |           \_ [a.out] <defunct>
 15950 pts/2    Z+     0:00          |           \_ [a.out] <defunct>
 15951 pts/2    Z+     0:00          |           \_ [a.out] <defunct>
 15952 pts/2    Z+     0:00          |           \_ [a.out] <defunct>
 15953 pts/2    Z+     0:00          |           \_ [a.out] <defunct>
 15954 pts/2    Z+     0:00          |           \_ [a.out] <defunct>
 15955 pts/2    Z+     0:00          |           \_ [a.out] <defunct>
 15956 pts/2    Z+     0:00          |           \_ [a.out] <defunct>
 15957 pts/2    Z+     0:00          |           \_ [a.out] <defunct>
 15958 pts/2    Z+     0:00          |           \_ [a.out] <defunct>
...
....
....
  3692 ?        Sl     0:02          \_ /usr/lib/x86_64-linux-gnu/notify-osd

여기에 사진 설명 삽입

이 실험에서는 부모 프로세스가 종료되지 않았으므로 모든 자식 프로세스의 부모 프로세스는 여전히 이전 부모 프로세스이며 init 프로세스로 전송되지 않습니다.

이때 201 개의 자식 프로세스의 프로세스 상태는 좀비 프로세스 인 Z +임을 알 수 있습니다. 그렇다면 좀비 프로세스는 무엇이며 좀비 프로세스는 어떻게 생성됩니까?

UNIX 용어에서 종료되었지만 부모 프로세스가 아직 처리하지 않은 프로세스 (자식 프로세스 종료 및 여전히 차지하고있는 리소스 해제에 대한 정보 획득)는 좀비 프로세스가됩니다.

따라서 위의 예에서 상위 프로세스는 201 개의 하위 프로세스를 포크합니다. 상위 프로세스가 하위 프로세스의 종료 상태를 얻기 위해 대기하지 않는 한 이러한 하위 프로세스는 위와 같이 종료 후 좀비 프로세스가됩니다. 자식 프로세스의 여파에 대해서는 wait () / waitpid ()를 사용하여 처리합니다. 이에 대해서는 다음 섹션에서 자세히 설명합니다.

참고로, 초기화 프로세스에서 채택한 프로세스가 종료되면 어떻게됩니까? 그가 좀비 프로세스가 될까요?

대답은 아니오입니다. init 프로세스는 자식 프로세스가 종료 될 때마다 init가 wait () 함수를 호출하여 처리하고 종료 상태를 얻도록 설계되었습니다. 이것은 시스템이 좀비 프로세스로 채워지는 것을 방지합니다.

추천

출처blog.csdn.net/LinuxArmbiggod/article/details/113794652