僵尸进程

1.僵尸进程与孤儿进程

  • 僵尸进程:如果子进程先于父进程退出,此时子进程便成为一个尸体;此前,如果父进程没有调用wait等相关系统调用,那么子进程便成为僵尸进程.

  • 孤儿进程:如果父进程先于子进程退出,那么子进程变成为孤儿进程,将被init进程领养.

2.进程相关数据结构

  • 进程控制块PCB:保留了进程运转时所需要的全部信息,是进程表中的一个entry.

当以fork()系统调用建立一个新的进程后,核心进程就会在进程表中给这个新进程分配一个PCB,然后将相关信息存储在该进入点所对应的进程表内。这些信息中有一项是其父进程的识别码。当这个进程走完了自己的生命周期后,它会执行exit()系统调用,此时原来进 程表中的数据会被该进程的退出码(exit code)、执行时所用的CPU时间等数据所取代,这些数据会一直保留到系统将它传递给它的父进程为止。由此可见,defunct进程的出现时间是在子进 程终止后,但是父进程尚未读取这些数据之前。

3.linux中的进程操作命令

我们主要来讲解ps\pgrep\pkill三个命令

  • ps:report a snapshot of the current processes.

To see every process on the system using standard syntax:
ps -ef

  1 UID        PID  PPID  C STIME TTY          TIME CMD                                                                                               
  2 root         1     0  0 Mar09 ?        00:00:01 /sbin/init

To see every process on the system using BSD syntax:
ps aux

1 USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
2 root         1  0.0  0.0  24588  2364 ?        Ss   Mar09   0:01 /sbin/init

pgrep和pkill不详细解释了.需要注意的是,上述三个命令得到的都是PCB中的信息.对于僵尸进程,
仍然存在PCB,所以这类进程虽然已经停止,但是用pgrep仍然可以找到,而且无法用pkill杀死.

4.如何杀死僵尸进程

其实用”杀死”已经不是很严密了,因为僵尸进程已经”死了”.准确说是清除僵尸进程的PCB. 由于kill和pkill命令是通过给进程发送信号来让进程退出的,而僵尸进程产生的原因: 父进程没有wait子进程结束也没有安装信号处理函数,况且进程”已经死了”,所以也无法接受信号.

我们用另外一种方法来彻底清除僵尸进程: 杀死僵尸进程的父进程,从而让僵尸进程被init进程接管.

ps -ef | grep defunct_process_pid | xargs pkill

5.如何避免产生僵尸进程

1.设置SIGCLD信号为SIG_IGN,系统将不产生僵死进程。
2.用两次fork(),而且使紧跟的子进程直接退出,使得孙子进程成为孤儿进程,从而init进程将负责清除这个孤儿进程。

那么问题来了:Q1:信号的作用原理是什么?
Q2:init进程是如何负责清除孤儿进程的?方法2中的子进程怎么办?为何不直接一次fork,然后调用wait系统调用?

关于这些疑问,我们可以参考系列文章:
linux信号原理
init进程的作用与工作原理
wait系统调用

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值