Linux System Programming 35 Process Control-init Process and Zombie Process

The following program, namely fork () to find the prime number change:

Experiment 1 The parent process does not sleep, and 201 child processes sleep

#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);
}

Change: Sleep for 1000 seconds before each child process ends. In this case, the parent process must end first, and after 201 child processes end. In this case, the parent process directly exit() after creating 201 child processes, and the child process sleeps after finishing its work.

ps axf view process status:

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
...
...
...

Insert picture description here

You can see that all the 201 child processes are written by the top grid, so the parent process of the 201 process is the init process

For all processes whose parent process has terminated, their parent process is changed to init process, we call these processes adopted by init process. The operation process is roughly as follows: When a process A terminates, the kernel will check all other active processes BCD...etc. to determine whether these active processes are child processes of terminating process A, and if so, the parent of the active process The process is changed to 1 (the ID of the init process is 1). This approach ensures that every process has a parent process.

Experiment 2 The parent process sleeps, the child process does not sleep

#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

Insert picture description here

In this experiment, since the parent process did not exit, the parent process of all child processes is still the previous parent process and is not transferred to the init process.

It can be seen that the process status of the 201 child processes at this time is Z+, which is the zombie process. So what is a zombie process and how are zombie processes generated?

In UNIX terminology, a process that has been terminated, but its parent process has not yet dealt with it (obtain information about terminating the child process, and release the resources it still occupies) becomes a zombie process.

So for the above example, the parent process forks 201 child processes. Unless the parent process waits to obtain the termination status of the child process, these child processes will become zombie processes after termination, as above. Regarding the aftermath of the child process, use wait()/waitpid() to deal with it, which will be explained in detail in the next section.

One more note, what happens when a process adopted by the init process terminates? Will he become a zombie process?

The answer is no. The init process is designed so that whenever a child process terminates, init will call a wait() function to deal with it and get its termination status. This prevents the system from being filled with zombie processes.

Guess you like

Origin blog.csdn.net/LinuxArmbiggod/article/details/113794652