Linux process 4: Orphan process, zombie process (and solution), daemon process explanation

Orphan process, zombie process (and solution), daemon process explanation

Orphan process:

If the parent process does not wait for the child process to exit, it ends its "life" before the child process. At this time, the child process is called an orphan process. ====Father is gone.
Linux avoids too many orphan processes in the system,init processThe acceptance of the orphan process becomes the parent process of the orphan process. ====init adoptive father

Zombie process:

After the child process is created, the exit status of the child process is not collected and becomes a zombie process.Dad don't want it
unless
After father died
Orphaninit adoptive fatherreceive. If the parent process is an endless loop, then the zombie process becomesWandering ghostConsume space.

Daemon:

Daemon is a type of program that is executed in the background from the terminal. It usually ends with d and starts with the system. Its parent process (ppid) is usuallyinit process。====Little angel backstage

1. Orphan process:

Case demonstration:

Example: The following is a sample program of an orphan process. In this program, let the parent process exit first, and then the child process prints its parent process number again:

#include<stdio.h>
#include<stdlib.h>
#include<errno.h>
#include<unistd.h>
int main()
{
    
    
pid_t pid;
pid = fork();//创建一个进程
if (pid < 0)
{
    
    
perror("fork error:");//创建失败
exit(1);
}
//子进程
if (pid == 0)
{
    
    
printf("I am the childprocess.\n");
//输出进程ID和父进程ID
printf("pid:%d\tppid:%d\n",getpid(),getppid());
printf("I will sleep fiveseconds.\n");
//睡眠5s,保证父进程先退出
sleep(5);
printf("pid:%d\tppid:%d\n",getpid(),getppid());
printf("child process isexited.\n");
}
//父进程
else
{
    
    
printf("I am fatherprocess.\n");
//父进程睡眠1s,保证子进程输出进程id
sleep(1);
printf("father process is  exited.\n");
}
return 0;
}

note: The
getpid function can get the pid of the current process, and the getppid function can get the parent process number of the current process.

operation result:

Insert picture description here
Description:
First print the IDs of the child process and the parent process, and then the parent process terminates early, and the child process becomes an orphan process, and print the child process and init parent process ID.

2. Zombie process:

A process uses fork to create a child process, if the child process exits, and the parent process does not callwait或waitpidGet the status information of the child process, then the process descriptor of the child process is still stored in the system. This kind of process is called a zombie process.

note: The
zombie process also consumes certain system resources, and also retains some summary information for the parent process to query the status of the child process to provide the information the parent process wants. Once the parent process gets the desired information, the zombie process will end.

How the zombie process is generated:

When a process calls the exit command to end its life, it is not actually destroyed, but a data structure called a zombie process (Zombie) is left (the system calls exit, which is used to make the process exit. But it is only limited to turning a normal process into a zombie process, and it cannot be completely destroyed).

In the state of Linux processes, zombie processes are a very special kind.It has given up almost all the memory space, does not have any executable code, and cannot be scheduled. It only reserves a position in the process list to record the exit status of the process for other processes to collect. In addition, the zombie process does not Take up any more memory space. It needs its parent process to collect corpses for it. If its parent process does not install the SIGCHLD signal processing function and calls wait or waitpid() to wait for the end of the child process, and does not explicitly ignore the signal, then it remains in the zombie state. At this time, the parent process ends, then the init process will automatically take over the child process and collect the body for it, and it can still be cleared. But if the parent process is a cycle and will not end, then the child process will remain in the zombie state, which is why there are sometimes many zombie processes in the system.

How to view the zombie process:

Use commands:ps, You can see that there are marked asWITHThe process is a zombie process.

How to clear the zombie process:

method one:

Rewrite the parent process and collect the corpse for the child process after it dies.
The specific method is to take over the SIGCHLD signal. After the child process dies, it sends a SIGCHLD signal to the parent process. After receiving this signal, the parent process executes the waitpid() function to collect the corpse for the child process. This is based on the principle: even if the parent process does not call wait, the kernel will send it a SIGCHLD message, although the default processing is to ignore, if you want to respond to this message, you can set a processing function.

Method Two:

Kill the parent process. After the parent process dies, the zombie process becomes an "orphan process", and the init process is adopted, and init is always responsible for cleaning up the zombie process. All zombie processes it spawned also disappeared.
Note: Zombie processes will lead to waste of resources, while orphans will not

Case demonstration 1:

Example 1: The following is an example program of a zombie process. In this program, the child process exits first, and the parent process does not call wait() or waitpid() to clean up the child process information.

#include<stdio.h>
#include<unistd.h>
#include<errno.h>
#include<stdlib.h>
int main()
{
    
    
pid_t pid;
pid = fork();
if (pid < 0)
{
    
    
perror("fork error:");
exit(1);
}
else if (pid == 0)
{
    
    
printf("I am child process.I amexiting.\n");
exit(0);
}
printf("I am father process.I willsleep two seconds\n");
//等待子进程先退出
sleep(2);
//输出进程信息
system("ps -opid,ppid,state,tty,command");
printf("father process isexiting.\n");
return 0;
}

operation result:
Insert picture description here
Description: The
child process becomes a zombie process

Case demonstration 2:

Example 2: The parent process cyclically creates the child process, and the child process exits, causing multiple zombie processes.

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<errno.h>
int main()
{
    
    
pid_t pid;
//循环创建子进程
while(1)
{
    
    
pid = fork();
if (pid < 0)
{
    
    
perror("fork error:");
exit(1);
}
else if (pid == 0)
{
    
    
printf("I am a childprocess.\nI am exiting.\n");
//子进程退出,成为僵尸进程
exit(0);
}
else
{
    
    
//父进程休眠20s继续创建子进程
sleep(4);
continue;
}
}
return 0;
}

operation result:

Insert picture description here
3. Zombie process solution:

Through the signal mechanism:

When the child process exits, the SIGCHILD signal is sent to the parent process, and the parent process processes the SIGCHILD signal. Call wait in the signal processing function to handle the zombie process. The test procedure is as follows:

#include<stdio.h>
#include<unistd.h>
#include<errno.h>
#include<stdlib.h>
#include<signal.h>
static voidsig_child(int signo);
int main()
{
    
    
pid_t pid;
//创建捕捉子进程退出信号
signal(SIGCHLD,sig_child);
pid = fork();
if (pid < 0)
{
    
    
perror("fork error:");
exit(1);
}
else if (pid == 0)
{
    
    
printf("I am child process,pid id%d.I am exiting.\n",getpid());
exit(0);
}
printf("I am father process.I willsleep two seconds\n");
//等待子进程先退出
sleep(2);
//输出进程信息
system("ps -opid,ppid,state,tty,command");
printf("father process isexiting.\n");
return 0;
}
static voidsig_child(int signo)
{
    
    
pid_t pid;
int stat;
//处理僵尸进程
while ((pid = waitpid(-1, &stat, WNOHANG))>0)
printf("child %dterminated.\n", pid);
}

operation result:
Insert picture description here

Two fork():

Section 8.6 of "Advanced Programming in Unix Environment" is very detailed. The principle is to turn the child process into an orphan process, so that its parent process becomes an init process, and the zombie process can be handled through the init process. The test procedure is as follows:

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<errno.h>
#include <sys/types.h>
#include <sys/wait.h>
int main()
{
    
    
pid_t pid;
//创建第一个子进程
pid = fork();
if (pid < 0)
{
    
    
perror("fork error:");
exit(1);
}
//第一个子进程
else if (pid == 0)
{
    
    
//子进程再创建子进程
printf("I am the first childprocess.pid:%d\tppid:%d\n",getpid(),getppid());
pid = fork();
if (pid < 0)
{
    
    
perror("fork error:");
exit(1);
}
//第一个子进程退出
else if (pid >0)
{
    
    
printf("first procee isexited.\n");
exit(0);
}
//第二个子进程
//睡眠3s保证第一个子进程退出,这样第二个子进程的父亲就是init进程里
sleep(3);
printf("I am the second childprocess.pid: %d\tppid:%d\n",getpid(),getppid());
exit(0);
}
//父进程处理第一个子进程退出
if (waitpid(pid, NULL, 0) != pid)
{
    
    
perror("waitepid error:");
exit(1);
}
exit(0);
return 0;
}

operation result:

Insert picture description here
Description: The
parent process becomes the init process.

4. The daemon:

Similarly, we need to understand what a daemon is,A daemon is a process that runs in the background and is not associated with any terminal, Normally the daemonRuns when the system starts,theyAs root userOr other special users (apache and postfix) run, and can handle some system-level tasks. Traditionally, the name of the daemond end (sshd), But these are not required.

A daemon is a process that is separated from the terminal and runs in the background.The daemon process is separated from the terminal in order to prevent the information in the process of execution from being displayed on any terminal, And the process will not be interrupted by the terminal information generated by any terminal.

The daemon process, also known as the Daemon process, is a background service process in Linux. It is a long-lived process, usually independent of the control terminal and periodically performs a certain task or waits to process certain events.The daemon is usually started when the system is booted and terminated when the system is shut downThere are many daemons in the Linux system, and most services are implemented through daemonsAt the same time, the daemon process can also complete many system tasks, such as job planning process crond, printing process lqd, etc. (the ending letter d here means Daemon).

Because in Linux, the interface for each system to communicate with users is called a terminal, and every process that runs from this terminal will be attached to this terminal. This terminal is called the control terminal of these processes. When the control terminal is closed, The corresponding process will be automatically closed. But the daemon can break through this limitation,It starts to run from being executed, and then exits when the entire system is shut down. If you want a process not to be affected by user or terminal or other changes, you must turn this process into a daemon.

Here are the steps to create a daemon:

· Call fork() to create a new process, it will be the future daemon.
· Call exit in the parent process to ensure that the child process is not the process group leader
· Call setsid() to create a new session area
· Change the current directory to follow Directory (if the current directory is used as the directory of the daemon process, the current directory cannot be uninstalled as the working directory of the daemon process)
Redirect standard input, mark output, and standard error to /dev/null

Code demo:

#include<sys/types.h>
#incldue<sys/stat.h>
#include<unistd.h>
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<signal.h>
#include<errno.h>
#include<signal.h>
#include<fcntl.h>
#incldue<unistd.h>
#include<linux/fs.h>
int main(void)
{
    
    
pid_t pid;
int i;
pid = fork();    //创建一个新进程,将来会是守护进程
if(pid == -1)
{
    
    
return -1;
}
else if(pid != 0){
    
     //父进程调用exit,保证子进程不是进程组长
exit(EXIT_SUCCESS);
}  
if(setsid() == -1) //创建新的会话区
{
    
    
return -1;        
}   
if(chdir("/") == -1)  //将当前目录改成根目录
{
    
    
return -1;
}  
for(i = 0;i < NR_OPEN;i++)
{
    
    
close(i);
}
open("/dev/null",O_RDWR); 重定向
dup(0);
dup(0);   
return 0;
}

operation result:

disda    26217     1 0 
06:59 ?        00:00:00 ./dm01_demon 则出现了守护进程!

5. Frequently Asked Questions:

Is the orphan process harmful?

An orphan process is a process without a parent process. The important task of the orphan process falls on the init process. The init process is like a civil affairs bureau, which is responsible for handling the aftermath of the orphan process. Whenever an orphan process appears, the kernel sets the parent process of the orphan process to init, and the init process will cyclically wait() its child processes that have exited. In this way, when an orphan process bleakly ends its life cycle, the init process will handle all its aftermath work on behalf of the party and government. Therefore, the orphan process is not harmful.

Are zombie processes harmful?

Zombie process harm scene: "Capture the thief first capture the king".

For example, there is a process that periodically spawns a child process. The child process needs to do very little and exits after doing what it should do. Therefore, the life cycle of the child process is very short, but the parent process only takes care of Generate a new child process. As for the things after the child process exits, it will be ignored. In this way, after the system runs for a period of time, there will be many dead processes in the system. If you use the ps command to view it, you will see To many processes with status Z. Strictly speaking, the dead process is not the source of the problem. The culprit is the parent process that produced a large number of dead processes. Therefore, when we seek to eliminate a large number of zombie processes in the system, the answer is to shoot the culprit that produced a large number of zombie processes (that is, send SIGTERM or SIGKILL signals through kill). After the culprit process (the parent process) is shot, the zombie process that it generates becomes an orphan process. These orphan processes will be taken over by the init process. The init process will wait() these orphan processes and release the system process table they occupy Resources, in this way, these dead orphan processes can be ignored. This is the role of the daemon process. If a large number of zombie processes occur, the daemon process will find its parent process and kill it mercilessly!

What should try to avoid zombie processes?

First of all, we must understand that a zombie process is not a living process, it can be said to be a data structure. It is the process of a completed task, but it will not disappear after it completes the task. It will leave something behind. This thing is his Process Id, its end status, etc. Why is this thing left? Because this is used to report its completion status to his parent process, think about why the parent process creates a process to complete the task, the parent process needs to know the completion of the child process, all such mechanisms appear , For the zombie process, only the parent process can clean it up, calling wait and other commands. That's it. But what if the parent process is not cleaned up, then it means that the zombie process exists, and the process ID is wasted. The process id is a limited resource. Use one and one less. So if a large number of zombie processes exist, the solution can be to kill Unscrupulous father, the child can be adopted. Therefore, the number of processes in the system is limited. Although the zombie process occupies less resources and memory, it occupies the number, which may cause the system to be unable to create new processes. Therefore, it is important to clear the zombie process in time!

supplement

Common commands in Linux: Common commands
used for file operations:
cp (copy), rm (delete), mkdir (create), cd (switch directory), mv (rename), ls (list files/folders), tar (Decompression), chmod (change permissions), chown (change owner)
common commands used for system process operations:
top/htop (view the real-time running status of all processes in the system), ps (list the processes in the system), lsof (check whether a port is occupied), kill (kill a process), iotop (monitor disk I/O), ifconfig (check the local IP)

Guess you like

Origin blog.csdn.net/weixin_40734514/article/details/108990454