孤儿/僵尸进程——回收子进程

参考博客:https://blog.csdn.net/qq_35396127/article/details/78725915

    :https://www.cnblogs.com/Anker/p/3271773.html

  在Linux下,子进程可由父进程创建,子进程也可以创建新的进程。但是父进程无法预测子进程的运行状态,不知道子进程何时会结束。由此会产生孤儿进程与僵尸进程。所以当一个进程结束后,它的父进程需要调用wait(),waitpid()系统调用获取子进程终止状态,回收子进程。

  什么是孤儿进程与僵尸进程?

  孤儿进程:

  父进程先于子进程结束,则子进程失去父进程,子进程就会被init 进程收养,子进程就成为孤儿进程。

 #include <stdio.h>
#include <stdlib.h>
#include <unistd.h> int main(void)
{
pid_t pid;
int i=;
//创建一个子进程
pid = fork(); if(pid == -)
{
perror("fork");
exit(); //1:异常退出 0:正常退出
}
else if(pid>)
{
printf("I am parent, my pid=%d\n",getpid());
sleep(); //父进程运行4秒后结束
printf("---------parent going to die-----------\n"); }
else
{
while(i<)
{
//待父进程结束后会被init收养
printf("I am child, pid = %d, parentpid = %d\n",getpid(),getppid());
sleep();
i++;
}
}
return ;
}

结果:

有的Ubuntu版本,会设置user init 进程专门处理孤儿进程

僵尸进程:

  子进程终止,父进程未回收子进程的资源PCB,使其变成僵尸进程。

测试程序:

 #include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <stdlib.h> int main(){ pid_t pid;
pid = fork();
if(pid < )
{
perror("fork error:");
exit();
}
else if (pid == )
{
printf("I am child, I am exiting.\n");
exit();
} printf("I am parent,I will sleep 2s\n");
//等待子进程先退出
sleep();
//输出进程信息
system("ps -o pid,ppid,state,tty,command");
printf("father process exiting\n"); return ;
} 源自:https://www.cnblogs.com/Anker/p/3271773.html

结果:

  孤儿进程与僵尸进程的危害

  在Linux中,每个进程退出时,内核会释放该进程所有资源,包括打开的文件,占用的内存等,但仍为之保留一定信息,包括:进程ID,退出状态,运行时间等。直到父进程通过wait/waitpid来取时,才会释放。因此,只要进程一直调用wait与waitpid,进程占用的资源就不会释放,进程号也不会释放,由于系统能使用的进程号是有限的,就可能因为大量僵尸进程占用进程号而不能产生新进程。当系统中产生大量僵尸进程时,应该把产生僵尸进程的父进程给杀死掉。可以通过kill发送SIGTERM或者SIGKILL信号,之后僵尸进程会因为没了父进程变成孤儿,被init收养再释放。

  对于孤儿进程,会被init进程收养,而且init进程会循环地wait()它收养的子进程。所以孤儿进程并无危害。

  通过信号机制解决僵尸进程

  子进程退出时会向父进程发送SIGCHLD信号,父进程调用信号处理函数,进而调用wait处理僵尸进程。测试程序:

 #include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <stdlib.h>
#include <signal.h> static void handlefunc(int sig)
{
pid_t pid;
int stat; //处理僵尸进程
//waitpid(-1:回收任一子进程,子进程结束状态,不阻塞父进程)
//waitpid成功返回子进程pid
while((pid = waitpid(-, &stat, WNOHANG))>)
printf("child %d terminated. \n",pid);
} int main()
{
pid_t pid;
//创建signal,捕捉子进程退出信号
signal(SIGCHLD,handlefunc);
pid = fork();
if(pid<)
{
perror("fork error:");
exit();
}
else if(pid == )
{
printf("I am chid, pid=%d. I exiting\n",getpid());
exit();
}
printf("I am parent. I sleep 3S\n");
//等待子进程退出
sleep();
//输出进程信息
system("ps -o pid,ppid,state,tty,command");
printf("parent exiting"); return ; }

结果:僵尸进程消失

signal(SIGCLD,SIG_IGN);

因为并发服务器常常fork很多子进程,子进程终结之后需要服务器进程去wait清理资源。如果将此信号的处理方式设为忽略,可让内核把僵尸子进程转交给init进程去处理,省去了大量僵尸进程占用系统资源。

详见:https://blog.csdn.net/u012317833/article/details/39253793

回收子进程——wait/waitpid 与 信号机制的更多相关文章

  1. 在Linux中简单实现回收子进程

    学习到wait函数了,这个函数的作用是用来回收进程.一般来说,正常退出的进程是不需要我们来专门回收的.但是进程有这两种:孤儿进程和僵尸进程. 孤儿进程: 通俗点说就是父进程先于子进程死亡.此时子进程就 ...

  2. Linux-父进程wait回收子进程

    1.wait工作原理 (1).子进程结束时,系统向其父进程发送SIGCHILD信号 (2).父进程调用wait函数后阻塞 (3).父进程被SIGCHILD信号唤醒然后去回收僵尸子进程 (4).父子进程 ...

  3. linux信号机制与python信号量

    1.信号本质 软中断信号(signal,又简称为信号)用来通知进程发生了异步事件.在软件层次上是对中断机制的一种模拟,在原理上,一个进程收到一个信号与处理器收到一个中断请求可以说是一样的.信号是进程间 ...

  4. Linux信号机制

    Linux信号(signal) 机制分析 [摘要]本文分析了Linux内核对于信号的实现机制和应用层的相关处理.首先介绍了软中断信号的本质及信号的两种不同分类方法尤其是不可靠信号的原理.接着分析了内核 ...

  5. linux下 signal信号机制的透彻分析与各种实例讲解

    转自:http://blog.sina.com.cn/s/blog_636a55070101vs2d.html 转自:http://blog.csdn.net/tiany524/article/det ...

  6. python使用信号机制实例:

    python使用信号机制实例: 程序会一直等待,直到其他程序发送CTRL-C信号给本进程.需要其他程序配合测试. 或者打开新的终端使用kill -sig PID 向一个进程发送信号,来测试. from ...

  7. Inside Flask - signal 信号机制

    Inside Flask - signal 信号机制 singal 在平常的 flask web 开发过程中较少接触到,但对于使用 flask 进行框架级别的开发时,则必须了解相关的工作机制.flas ...

  8. linux信号机制 - 用户堆栈和内核堆栈的变化【转】

    转自:http://itindex.net/detail/16418-linux-%E4%BF%A1%E5%8F%B7-%E5%A0%86%E6%A0%88 此文只简单分析发送信号给用户程序后,用户堆 ...

  9. 利用linux信号机制调试段错误(Segment fault)

    在实际开发过程中,大家可能会遇到段错误的问题,虽然是个老问题,但是其带来的隐患是极大的,只要出现一次,程序立即崩溃中止.如果程序运行在PC中,segment fault的调试相对比较方便,因为可以通过 ...

随机推荐

  1. AbstractQueuedSynchronizer简单使用

    AQS是JUC中很多同步组件的构建基础,简单来讲,它内部实现主要是状态变量state和一个FIFO队列来完成,同步队列的头结点是当前获取到同步状态的结点,获取同步状态state失败的线程,会被构造成一 ...

  2. Linux如何查看进程是否存活

    ps  -ef  | grep nginx ps -ef | grep(过滤) 进程名字

  3. 如何在MaxCompute上处理存储在OSS上的开源格式数据

    0. 前言 MaxCompute作为使用最广泛的大数据平台,内部存储的数据以EB量级计算.巨大的数据存储量以及大规模计算下高性能数据读写的需求,对于MaxCompute提出了各种高要求及挑战.处在大数 ...

  4. 网络体系之TCP/IP模型

    TCP/IP参考模型是因特网使用的参考模型,这个体系结构在它的两个主要协议出现以后,被称为TCP/IP参考模型.该模型将网络协议分为四层:网络接口层.网络层.运输层.应用层. TCP/IP协议不是TC ...

  5. 【UNR #2】黎明前的巧克力 解题报告

    [UNR #2]黎明前的巧克力 首先可以发现,等价于求 xor 和为 \(0\) 的集合个数,每个集合的划分方案数为 \(2^{|S|}\) ,其中 \(|S|\) 为集合的大小 然后可以得到一个朴素 ...

  6. 【Elasticsearch】ElasticSearch基本查询

    学习elasticsearch查询用法的时候,发现这篇文章写得很详细,为以后方便查看,就直接搬过来了,原文链接在下面. 版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附 ...

  7. element菜单默认展开和选中

    这两个属性, :default-openeds="openeds" default-active="/networkConfig"中设置的要与数组中的index ...

  8. SSM - 全局跨域处理

    这几天在开发中编写项目时需要前后端分离,刚好涉及到跨域这个问题,很早之前做项目时也用过,也是在网上找的列子,来源已经无处可寻了,若侵必删! 跨域问题一般出现两者服务器不同或者不同的端口上访问资源时会存 ...

  9. [HDU2276]Kiki & Little Kiki 2

    题目:Kiki & Little Kiki 2 链接:http://acm.hdu.edu.cn/showproblem.php?pid=2276 分析: 1)如果前一盏灯亮着,则改变这一盏灯 ...

  10. Review: 9-13 July

    9 July 并查集 int fa[]; for (int i=1; i<=n; ++i) fa[i]=i; int f(int x){return fa[x]==x?x:fa[x]=f(fa[ ...