1、孤儿进程:

孤儿进程:一个父进程退出,而它的一个或多个子进程还在运行,那么那些子进程将成为孤儿进程。孤儿进程将被init进程(进程号为1)所收养,并由init进程对它们完成状态收集工作。孤儿进程是没有父进程的进程,孤儿进程这个重任就落到了init进程身上,init进程就好像是一个民政局,专门负责处理孤儿进程的善后工作。每当出现一个孤儿进程的时候,内核就把孤儿进程的父进程设置为init,而init进程会循环地wait()它的已经退出的子进程。这样,当一个孤儿进程凄凉地结束了其生命周期的时候,init进程就会代表党和政府出面处理它的一切善后工作。因此孤儿进程并不会有什么危害。

模拟孤儿进程的产生:

#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <errno.h> int main(void)
{
pid_t pid ;
signal(SIGCHLD,SIG_IGN);
printf("before fork pid:%d\n",getpid());
int abc = ;
pid = fork();
if(pid == -)
{
perror("tile");
return -;
}
if(pid > ) //父进程先退出
{
abc++;
printf("parent:pid:%d \n",getpid());
printf("abc:%d \n",abc);
sleep();
}
else if(pid == ){ //子进程后退出,被托付给init进程
abc++;
printf("child:%d,parent: %d\n",getpid(),getppid());
printf("abc:%d",abc);
sleep();
}
printf("fork after...\n");
}

输出:

before fork pid:27709
parent:pid:27709 
abc:11 
child:27710,parent: 27709
fork after...

然后我们使用命令:ps -ef查看,PPID 为1的这个进程为上述程序产生的孤儿进程。

2、僵尸进程:

僵尸进程是当子进程比父进程先结束,而父进程又没有回收子进程,释放子进程占用的资源,此时子进程将成为一个僵尸进程。如果父进程先退出 ,子进程被init接管,子进程退出后init会回收其占用的相关资源
我们都知道进程的工作原理。我们启动一个程序,开始我们的任务,然后等任务结束了,我们就停止这个进程。 进程停止后, 该进程就会从进程表中移除。在UNIX 系统中,一个进程结束了,但是他的父进程没有等待(调用wait / waitpid)他, 那么他将变成一个僵尸进程。 但是如果该进程的父进程已经先结束了,那么该进程就不会变成僵尸进程, 因为每个进程结束的时候,系统都会扫描当前系统中所运行的所有进程, 看有没有哪个进程是刚刚结束的这个进程的子进程,如果是的话,就由Init 来接管他,成为他的父进程……
僵尸进程的危害:
由于子进程的结束和父进程的运行是一个异步过程,即父进程永远无法预测子进程到底什么时候结束. 那么会不会因为父进程太忙来不及wait子进程,或者说不知道子进程什么时候结束,而丢失子进程结束时的状态信息呢? 不会。因为UNⅨ提供了一种机制可以保证只要父进程想知道子进程结束时的状态信息, 就可以得到。这种机制就是: 在每个进程退出的时候,内核释放该进程所有的资源,包括打开的文件,占用的内存等。但是仍然为其保留一定的信息(包括进程号the process ID,退出状态the termination status of the process,运行时间the amount of CPU time taken by the process等)。直到父进程通过wait / waitpid来取时才释放. 但这样就导致了问题,如果进程不调用wait / waitpid的话,那么保留的那段信息就不会释放,其进程号就会一直被占用,但是系统所能使用的进程号是有限的,如果大量的产生僵死进程,将因为没有可用的进程号而导致系统不能产生新的进程. 此即为僵尸进程的危害,应当避免。
模拟僵尸进程的产生:
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <errno.h>
int main(void)
{
pid_t pid ;
//signal(SIGCHLD,SIG_IGN);
printf("before fork pid:%d\n",getpid());
int abc = ;
pid = fork();
if(pid == -)
{
perror("tile");
return -;
}
if(pid > )
{
abc++;
printf("parent:pid:%d \n",getpid());
printf("abc:%d \n",abc);
sleep();
}
else if(pid == ){
abc++;
printf("child:%d,parent: %d\n",getpid(),getppid());
printf("abc:%d",abc);
exit();
}
printf("fork after...\n");

在父进程休眠的20秒内,产生了僵尸进程,此时可以打开另一个终端,命令ps -ef查看到:

admin 29696 29695 0 20:04 pts/1 00:00:00 [zombie] <defunct>

即我们模拟出来的僵尸进程。

避免僵尸进程的方式:

⒈ 父进程通过wait和waitpid等函数等待子进程结束,这会导致父进程挂起。
⒉ 如果父进程很忙,那么可以用signal函数为SIGCHLD安装handler,因为子进程结束后, 父进程会收到该信号,可以在handler中调用wait回收。
⒊ 如果父进程不关心子进程什么时候结束,那么可以用signal(SIGCHLD,SIG_IGN) 通知内核,自己对子进程的结束不感兴趣,那么子进程结束后,内核会回收, 并不再给父进程发送信号。
⒋ 还有一些技巧,就是fork两次,父进程fork一个子进程,然后继续工作,子进程fork一 个孙进程后退出,那么孙进程被init接管,孙进程结束后,init会回收。不过子进程的回收 还要自己做。
 
杀死僵尸进程的方法:
一般僵尸进程很难直接kill掉,不过您可以kill僵尸爸爸。父进程死后,僵尸进程成为”孤儿进程”,过继给1号进程init,init始终会负责清理僵尸进程.它产生的所有僵尸进程也跟着消失。
 
3、守护进程:
守护进程:
http://www.cnblogs.com/mickole/p/3188321.html

【Linux 进程】孤儿进程、僵尸进程和守护进程的更多相关文章

  1. linux分享六:nohup与&,守护进程

    contab每秒执行脚本,然后将把标准错误重定向到标准输出(2>&1)以追加的方式写入log_cronjob.txt.补充:试想2>1代表什么,2与>结合代表错误重定向,而1 ...

  2. Linux Rsync备份服务介绍及部署守护进程模式

    rsync介绍 rsync是一款开源的.快速的.多功能的.可实现全量及增量的本地或远程数据同步备份工具 在常驻模式(daemon mode)下,rsync默认监听TCP端口873,以原生rsync传输 ...

  3. (并发编程)进程IPC,生产者消费者模型,守护进程补充

    一.IPC(进程间通信)机制进程之间通信必须找到一种介质,该介质必须满足1.是所有进程共享的2.必须是内存空间附加:帮我们自动处理好锁的问题 a.from multiprocessing import ...

  4. linux下为.net core应用创建守护进程

    1.Supervisor 安装 yum install python-setuptools easy_install supervisor 2.配置 Supervisor mkdir /etc/sup ...

  5. [Linux]使用PHP编写Gearman的Worker守护进程

    在我之前的文章中,介绍过Gearman的使用.在我的项目中,我使用了PHP来编写一直运行的Worker.如果按照Gearman官方推荐的例子,只是简单的一个循环来等待任务,会有一些问题,包括:1.当代 ...

  6. 二十三、Linux 进程与信号---进程链和进程扇、守护进程和孤儿进程以及僵尸进程

    23.1 进程链和进程扇 23.1.1 概念 进程链:一个父进程构建出一个子进程,子进程再构建出子子进程,子子进程构建出子子子进程.... 这种就为进程链 进程扇:一个父进程构建出多个子进程,子进程都 ...

  7. Linux进程学习(孤儿进程和守护进程)

    孤儿进程和守护进程 通过前面的学习我们了解了如何通过fork()函数和vfork()函数来创建一个进程.现在 我们继续深入来学习两个特殊的进程:孤儿进程和守护进程 一.孤儿进程 1.什么是 孤儿进程如 ...

  8. Linux进程学习 - 孤儿进程和守护进程

    孤儿进程和守护进程 通过前面的学习我们了解了如何通过fork()函数和vfork()函数来创建一个进程.现在 我们继续深入来学习两个特殊的进程:孤儿进程和守护进程 一.孤儿进程 1.什么是 孤儿进程如 ...

  9. 并发编程(二)--利用Process类开启进程、僵尸进程、孤儿进程、守护进程、互斥锁、队列与管道

    一.multiprocessing模块 1.multiprocessing模块用来开启子进程,并在子进程中执行我们定制的任务(比如函数),该模块与多线程模块threading的编程接口类似. 2.mu ...

  10. Python进阶----进程间数据隔离, join阻塞等待, 进程属性, 僵尸进程和孤儿进程, 守护进程

    Python进阶----进程间数据隔离, join阻塞等待, 进程属性, 僵尸进程和孤儿进程, 守护进程 一丶获取进程以及父进程的pid 含义:    进程在内存中开启多个,操作系统如何区分这些进程, ...

随机推荐

  1. 阅读程序 回答问题——FindTheNumber

    阅读程序 回答问题——FindTheNumber 阅读下面程序,请回答如下问题:问题1:这个程序要找的是符合什么条件的数?问题2:这样的数存在么?符合这一条件的最小的数是什么?问题3:在电脑上运行这一 ...

  2. 关于cordova 状态栏设置

    https://blog.csdn.net/u011127019/article/details/58104056

  3. js数组方法解析

    js 数组有很多方法,其中有的常用,有的不常用,归纳几个常用的方法,做个总结: 1. 转换方法: 1.1 valueOf():调用这个方法会返回数组本身 <script> var arr ...

  4. Delphi XE8 中TIdTCPClient的WriteLn编码变化!

    //XE2中正常的代码: IdTCPClient1.IOHandler.WriteLn(sendData,TEncoding.ANSI); //XE8中不行了,解决方法: //,引入“IdGlobal ...

  5. Haskell语言学习笔记(76)Data.Tree

    Data.Tree data Tree a = Node { rootLabel :: a, subForest :: Forest a } deriving (Eq, Read, Show) typ ...

  6. TLS协议(安全传输层协议)

    概况 安全传输层协议(TLS)用于在两个通信应用程序之间提供保密性和数据完整性.该协议由两层组成: TLS 记录协议(TLS Record)和 TLS 握手协议(TLS Handshake).较低的层 ...

  7. webpack 自动发现 entry 的配置和引用方式

    假定我们的项目目录为如下的样子: - root/ - assets/ - app/ - global.js - index/ - index.js - auth/ - login.js - regis ...

  8. Visual studio 2019 preview & C# 8 initial experience

    Visual studio 2019 preview & C# 8 initial experience       using System; using static System.Con ...

  9. (Unity4.7)assetbundle 坑爹总结

    使用版本Unity4.7 一.关于依赖打包 1.当一个被打包的资源A引用了其他的资源B,并且没有被打成一个包时,要选用[BuildAssetBundleOptions.CollectDependenc ...

  10. UMD模式的js

    (function (root, factory) { if (typeof define === 'function' && define.amd) { // AMD define( ...