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

参考博客: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. mysql小知识

    char(10): 换行符 char(13): 回车符 UPDATE tablename SET field = REPLACE(REPLACE(field, CHAR(10), ”), CHAR(1 ...

  2. 特朗普或出席!富士康耗资100亿美元建LCD液晶面板厂

    富士康建液晶工厂,富士康科技集团发言人证实,富士康科技集团将于今年6月28日耗资100亿美元的LCD面板厂举行动工仪式. 富士康周四表示,他已经了解到,仪式将于今年6月28日举行,包括美国总统特朗普总 ...

  3. tensorflow函数介绍(1)

    tensorflow中的tensor表示一种数据结构,而flow则表现为一种计算模型,两者合起来就是通过计算图的形式来进行计算表述,其每个计算都是计算图上的一个节点,节点间的边表示了计算之间的依赖关系 ...

  4. vue cli3以上的项目中如何使用axois请求本地json文件

    首先明确一点,在vue cli3以上的版本中,存放静态资源的文件是public 我刚开始以为是和vue cli2一样需要放在static文件夹下,但是项目中没有这个文件夹,我就自己创建了一个,结果请求 ...

  5. 阿里云数据库备份DBS商业化发布,数据库实时备份到OSS

    数据库备份DBS已于2018年5月17日正式商业化发布. 数据库备份(Database Backup,简称DBS)是为数据库提供连续数据保护.低成本的备份服务. 它可以为多种环境的数据提供强有力的保护 ...

  6. sql 连接的使用说明

    SQL中的left outer join,inner join,right outer join用法详解 使用关系代数合并数据 关系代数 合并数据集合的理论基础是关系代数,它是由E.F.Codd于19 ...

  7. 9.27-uname,useradd命令

    打印系统信息 [root@wen ~]# uname Linux [root@wen ~]# uname -r #内核版本 2.6.32-573.el6.x86_64 [root@wen ~]# un ...

  8. BZOJ 1369: [Baltic2003]Gem(树形dp)

    传送门 解题思路 直接按奇偶层染色是错的,\(WA\)了好几次,所以要树形\(dp\),感觉最多\(log\)种颜色,不太会证. 代码 #include<iostream> #includ ...

  9. Unity编程标准导引-3.4 Unity中的对象池

    本文为博主原创文章,欢迎转载.请保留博主链接http://blog.csdn.net/andrewfan Unity编程标准导引-3.4 Unity中的对象池 本节通过一个简单的射击子弹的示例来介绍T ...

  10. jdk8的stream流式计算的操作

    jdk8之后增加了流式计算,现在根据学习了流式计算,并把过程记录下来: Person.java的bean package com.zhang.collectordemo; /** * @program ...