Linux zombie process is a process that has died long ago, but still occupies a position in the process table; if the parent process does not have wait() when the child process dies, you can usually see it displayed as "
", thus generating zombie processes; if a large number of zombie processes are generated, the system will not be able to generate new processes because there are no available process numbers, so zombie processes should be avoided.
The operating environment of this tutorial: linux5.9.8 system, Dell G3 computer.
The generation and avoidance of zombie processes (Defunct processes) under Linux
1. What is a zombie process
In the UNIX system, a process ends, but its parent The process does not wait (call wait/waitpid) for him, then he will become a zombie process. When you use the ps command to observe the execution status of the process, you will see that the status bar of these processes is defunct. A zombie process is a process that has died long ago, but still occupies a slot in the processes table.
But if the parent process of the process has ended first, then the process will not become a zombie process. Because when each process ends, the system will scan all processes running in the current system to see if any process is a child process of the process that just ended. If so, the Init process will take over it and become it. The parent process, thus ensuring that each process will have a parent process. The Init process will automatically wait for its child processes, so all processes taken over by Init will not become zombie processes.
2. How processes operate under UNIX
Each Unix process has an entry point (entry) in the process table, Core processUsed when executing the process All information received is stored at the entry point. When you use the ps command to view process information in the system, what you see is the relevant data in the process table. When a new process is created with the fork() system call, the core process will assign an entry point to the new process in the process table, and then store relevant information in the process table corresponding to the entry point. One of these pieces of information is the identification number of its parent process.
The end of the child process and the running of the parent process are an asynchronous process, that is, the parent process can never predict when the child process will end. So will the status information when the child process ends be lost because the parent process is too busy to wait for the child process, or because it does not know when the child process will end?
Won't. Because UNIX provides a mechanism to ensure that as long as the parent process wants to know the status information when the child process ends, it can get it. This mechanism is: when the child process completes its life cycle, it will execute the exit() system call, and the kernel releases all the resources of the process, including open files, occupied memory, etc. However, certain information is still retained for it (including the process ID, the exit code, the termination status of the process, the amount of CPU time taken by the process, etc.), and these data will be retained until the system Pass it to its parent process and not release it until the parent process fetch it via wait/waitpid.
In other words, when a process dies, it does not completely disappear. The process terminates, it is no longer running, but there is still some residual data waiting for the parent process to reclaim it. When a parent process forks() a child process, it must use wait() (or waitpid()) to wait for the child process to exit. It is this wait() action that makes the residual data of the child process disappear.
3. The harm of zombie processes
If the parent process does not call wait/waitpid, the retained information will not be released, and its process number will always be occupied, but the system The capacity of the process table is limited, and the process numbers that can be used are also limited. If a large number of zombie processes are generated, the system will not be able to generate new processes because there are no available process numbers.
So, defunct processes not only occupy the system's memory resources and affect the performance of the system, but also cause system paralysis if there are too many of them. Moreover, since the scheduler cannot select the Defunct process, the kill command cannot be used to delete the Defunct process. The only way is to restart the system.
4. Generation of zombie process
If the parent process does not have wait() when the child process dies, you can usually use ps to see that it is displayed as "
It can be seen that the defunct process appears after the child process terminates, but before the parent process has read the data. Taking advantage of this, we can use the following program to create a defunct process:
#include <stdio.h>
#include<sys>
main()
{
if(!fork())
{
printf(“child pid=%d\n”, getpid());
exit(0);
}
sleep(20);
printf(“parent pid=%d \n”, getpid());
exit(0);
}</sys></stdio.h>
当上述程序以后台的方式执行时,第17行强迫程序睡眠20秒,让用户有时间输入ps -e指令,观察进程的状态,我们看到进程表中出现了defunct进程。当父进程执行终止后,再用ps -e命令观察时,我们会发现defunct进程也随之消失。这是因为父进程终止后,init 进程会接管父进程留下的这些“孤儿进程”(orphan process),而这些“孤儿进程”执行完后,它在进程表中的进入点将被删除。如果一个程序设计上有缺陷,就可能导致某个进程的父进程一直处于睡眠状态或是陷入死循环,父进程没有wait子进程,也没有终止以使Init接管,该子进程执行结束后就变成了defunct进程,这个defunct 进程可能会一直留在系统中直到系统重新启动。
在看一个产生僵尸进程的例子。
子进程要执行的程序test_prog
//test.c
#include <stdio.h> int main() {
int i = 0;
for (i = 0 ; i </stdio.h>
父进程father的代码father.c
#include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <sys/wait.h> int main() { int pid = fork (); if (pid == 0) { system ("./test_prog"); _exit (0); }else { int i = 0; /* int status = 0; while (!waitpid(pid, &status, WNOHANG)) { printf ("father waiting%d\n", ++i); sleep (1); }*/ while (1) { printf ("father waiting over%d\n", ++i); sleep (1); } return 0; } }
执行./father,当子进程退出后,由于父进程没有对它的退出进行关注,会出现僵尸进程
20786 pts/0 00:00:00 father
20787 pts/0 00:00:00 father <defunct></defunct>
总结:子进程成为 defunct 直到父进程 wait(),除非父进程忽略了 SIGCLD 。更进一步,父进程没有 wait() 就消亡(仍假设父进程没有忽略 SIGCLD )的子进程(活动的或者 defunct)成为 init 的子进程,init 着手处理它们。
五、如何避免僵尸进程
1、父进程通过wait和waitpid等函数等待子进程结束,这会导致父进程挂起。
在上个例子中,如果我们略作修改,在第8行sleep()系统调用前执行wait()或waitpid()系统调用,则子进程在终止后会立即把它在进程表中的数据返回给父进程,此时系统会立即删除该进入点。在这种情形下就不会产生defunct进程。
2. 如果父进程很忙,那么可以用signal函数为SIGCHLD安装handler。在子进程结束后,父进程会收到该信号,可以在handler中调用wait回收。
3. 如果父进程不关心子进程什么时候结束,那么可以用signal(SIGCLD, SIG_IGN)或signal(SIGCHLD, SIG_IGN)通知内核,自己对子进程的结束不感兴趣,那么子进程结束后,内核会回收,并不再给父进程发送信号
4. fork两次,父进程fork一个子进程,然后继续工作,子进程fork一个孙进程后退出,那么孙进程被init接管,孙进程结束后,init会回收。不过子进程的回收还要自己做。 下面就是Stevens给的采用两次folk避免僵尸进程的示例:
#include "apue.h" #include <sys> int main(void) ...{
pid_t pid;
if ((pid = fork()) 0)
exit(0); /**//* parent from second fork == first child */
/**//*
* We're the second child; our parent becomes init as soon
* as our real parent calls exit() in the statement above.
* Here's where we'd continue executing, knowing that when
* we're done, init will reap our status.
*/
sleep(2);
printf("second child, parent pid = %d ", getppid());
exit(0);
}
if (waitpid(pid, NULL, 0) != pid) /**//* wait for first child */
err_sys("waitpid error");
/**//*
* We're the parent (the original process); we continue executing,
* knowing that we're not the parent of the second child.
*/
exit(0); }</sys>
相关推荐:《Linux视频教程》
The above is the detailed content of What is a linux zombie process?. For more information, please follow other related articles on the PHP Chinese website!

linux设备节点是应用程序和设备驱动程序沟通的一个桥梁;设备节点被创建在“/dev”,是连接内核与用户层的枢纽,相当于硬盘的inode一样的东西,记录了硬件设备的位置和信息。设备节点使用户可以与内核进行硬件的沟通,读写设备以及其他的操作。

区别:1、open是UNIX系统调用函数,而fopen是ANSIC标准中的C语言库函数;2、open的移植性没fopen好;3、fopen只能操纵普通正规文件,而open可以操作普通文件、网络套接字等;4、open无缓冲,fopen有缓冲。

端口映射又称端口转发,是指将外部主机的IP地址的端口映射到Intranet中的一台计算机,当用户访问外网IP的这个端口时,服务器自动将请求映射到对应局域网内部的机器上;可以通过使用动态或固定的公共网络IP路由ADSL宽带路由器来实现。

在linux中,交叉编译是指在一个平台上生成另一个平台上的可执行代码,即编译源代码的平台和执行源代码编译后程序的平台是两个不同的平台。使用交叉编译的原因:1、目标系统没有能力在其上进行本地编译;2、有能力进行源代码编译的平台与目标平台不同。

在linux中,eof是自定义终止符,是“END Of File”的缩写;因为是自定义的终止符,所以eof就不是固定的,可以随意的设置别名,linux中按“ctrl+d”就代表eof,eof一般会配合cat命令用于多行文本输出,指文件末尾。

在linux中,可以利用“rpm -qa pcre”命令判断pcre是否安装;rpm命令专门用于管理各项套件,使用该命令后,若结果中出现pcre的版本信息,则表示pcre已经安装,若没有出现版本信息,则表示没有安装pcre。

linux查询mac地址的方法:1、打开系统,在桌面中点击鼠标右键,选择“打开终端”;2、在终端中,执行“ifconfig”命令,查看输出结果,在输出信息第四行中紧跟“ether”单词后的字符串就是mac地址。

在linux中,rpc是远程过程调用的意思,是Reomote Procedure Call的缩写,特指一种隐藏了过程调用时实际通信细节的IPC方法;linux中通过RPC可以充分利用非共享内存的多处理器环境,提高系统资源的利用率。


Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

AI Hentai Generator
Generate AI Hentai for free.

Hot Article

Hot Tools

Zend Studio 13.0.1
Powerful PHP integrated development environment

Atom editor mac version download
The most popular open source editor

ZendStudio 13.5.1 Mac
Powerful PHP integrated development environment

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Dreamweaver Mac version
Visual web development tools
