博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
僵尸进程
阅读量:5955 次
发布时间:2019-06-19

本文共 2164 字,大约阅读时间需要 7 分钟。

  在每个进程退出的时候,内核释放该进程所有的资源,包括打开的文件,占用的内存等.但是仍然为其保留一定的信息(包括进程号the process ID,退出状态the termination status of the process,运行时间the amount of CPU time taken by the process等),直到父进程通过wait / waitpid来取时才释放,此时该进程便成为僵尸进程。

1.什么是僵尸进程?
    UNIX 系统中,一个进程结束了,但是他的父进程没有等待(调用wait / waitpid)他,而父进程还没有结束,那么他将变成一个僵尸进程.
    如果该进程的父进程已经先结束了,那么该进程就不会变成僵尸进程,因为每个进程结束的时候,系统都会扫描当前系统中所运行的所有进程,看有没有哪个进程是刚刚结束的这个进程的子进程,如果是的话,就由Init来接管他,成为他的父进程,从而保证每个进程都会有一个父进程.而Init进程会自动wait其子进程,因此被Init接管的所有进程都不会变成僵尸进程.

2.子进程结束后为什么要进入僵尸状态?

    因为父进程可能要取得子进程的退出状态等信息。

3.僵尸状态是每个子进程比经过的状态吗?

    是的。任何一个子进程(init除外)在exit()之后,并非马上就消失掉,而是留下一个称为僵尸进程(Zombie)的数据结构,等待父进程处理。这是每个 子进程在结束时都要经过的阶段。如果子进程在exit()之后,父进程没有来得及处理,这时用ps命令就能看到子进程的状态是“Z”。如果父进程能及时 处理,可能用ps命令就来不及看到子进程的僵尸状态,但这并不等于子进程不经过僵尸状态。
    如果父进程在子进程结束之前退出,则子进程将由init接管。init将会以父进程的身份对僵尸状态的子进程进行处理。

4.如何查看僵尸进程:

    $ ps -el
    其中,有标记为Z的进程就是僵尸进程
    S代表休眠状态;D代表不可中断的休眠状态;R代表运行状态;Z代表僵死状态;T代表停止或跟踪状态

5.僵尸进程的避免

    1、父进程通过wait和waitpid等函数等待子进程结束,这会导致父进程挂起
    2. 如果父进程很忙,那么可以用signal函数为SIGCHLD安装handler,因为子进程结束后,父进程会收到该信号,可以在handler中调用wait回收
    3. 如果父进程不关心子进程什么时候结束,那么可以用signal(SIGCHLD, SIG_IGN)通知内核,自己对子进程的结束不感兴趣,那么子进程结束后,内核会回收,并不再给父进程发送信号
    4. 还有一些技巧,就是fork两次,父进程fork一个子进程,然后继续工作,子进程fork一个孙进程后退出,那么孙进程被init接管,孙进程结束后,init会回收。不过子进程的回收还要自己做。

#include "apue.h"#include 
int main(void){ pid_t pid; if ((pid = fork()) < 0) { err_sys("fork error"); } else if (pid == 0) { /**//* first child */ if ((pid = fork()) < 0) err_sys("fork error"); else if (pid > 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);}

 

转载地址:http://ozexx.baihongyu.com/

你可能感兴趣的文章
黑马程序员—文件读取路径及行读取的方式,今晚总算有点小懂
查看>>
自己用的一套reset.css,打算整理一下方便以后用,持续更新中,各位大神,不喜勿喷...
查看>>
DBA_实践指南系列7_Oracle Erp R12监控OAM(案例)
查看>>
【HASH】【UVA 10125】 Sumset
查看>>
常用的Javascript设计模式
查看>>
[ACM] poj 2249 Binomial Showdown (排列组合公式优化)
查看>>
java9学习之模块化
查看>>
深入理解正则表达式
查看>>
C#_LINQ(LINQ to Entities)
查看>>
数据库主键与外键
查看>>
tidb 架构 ~Tidb学习系列(5)
查看>>
DOM
查看>>
Android ADB 常用命令
查看>>
通过jQuery.support看javascript中的兼容性问题
查看>>
SQL Server2014安装流程及注意事项
查看>>
Data - 信息获取途径汇总
查看>>
setInterval、setTimeout
查看>>
RookeyFrame 隐藏 首次加载菜单 的伸缩动画
查看>>
用C语言实现的轴对称变换
查看>>
陶哲轩实分析 推论 7.3.2 (比较判别法) 证明
查看>>