什么是PHP7中的孤儿进程与僵尸进程(2)

僵尸进程危害场景

例如有个进程,它定期的产 生一个子进程,这个子进程需要做的事情很少,做完它该做的事情之后就退出了,因此这个子进程的生命周期很短,但是,父进程只管生成新的子进程,至于子进程 退出之后的事情,则一概不闻不问,这样,系统运行上一段时间之后,系统中就会存在很多的僵死进程,倘若用ps命令查看的话,就会看到很多状态为Z的进程。 严格地来说,僵死进程并不是问题的根源,罪魁祸首是产生出大量僵死进程的那个父进程。因此,当我们寻求如何消灭系统中大量的僵死进程时,答案就是把产生大 量僵死进程的那个元凶枪毙掉(也就是通过kill发送SIGTERM或者SIGKILL信号啦)。枪毙了元凶进程之后,它产生的僵死进程就变成了孤儿进 程,这些孤儿进程会被init进程接管,init进程会wait()这些孤儿进程,释放它们占用的系统进程表中的资源,这样,这些已经僵死的孤儿进程 就能瞑目而去了。

孤儿进程和僵尸进程测试

1、孤儿进程被init进程收养

$pid = pcntl_fork();

if ($pid > 0) {

  // 显示父进程的进程ID,这个函数可以是getmypid(),也可以用posix_getpid()

  echo "Father PID:" . getmypid() . PHP_EOL;

  // 让父进程停止两秒钟,在这两秒内,子进程的父进程ID还是这个父进程

  sleep(2);

} else if (0 == $pid) {

  // 让子进程循环10次,每次睡眠1s,然后每秒钟获取一次子进程的父进程进程ID

  for ($i = 1; $i <= 10; $i++) {

    sleep(1);

    // posix_getppid()函数的作用就是获取当前进程的父进程进程ID

    echo posix_getppid() . PHP_EOL;

  }

} else {

  echo "fork error." . PHP_EOL;

}

测试结果:

php daemo001.php

Father PID:18046

18046

18046

www@iZ2zec3dge6rwz2uw4tveuZ:~/test$ 1

1

1

1

1

1

1

1

2、僵尸进程和危害 

执行以下代码 php zombie1.php

$pid = pcntl_fork();

if( $pid > 0 ){

  // 下面这个函数可以更改php进程的名称

  cli_set_process_title('php father process');

  // 让主进程休息60秒钟

  sleep(60);

} else if( 0 == $pid ) {

  cli_set_process_title('php child process');

  // 让子进程休息10秒钟,但是进程结束后,父进程不对子进程做任何处理工作,这样这个子进程就会变成僵尸进程

  sleep(10);

} else {

  exit('fork error.'.PHP_EOL);

}

执行结果,另外一个终端窗口

www@iZ2zec3dge6rwz2uw4tveuZ:~$ ps -aux|grep -v "grep\|nginx\|php-fpm" | grep php

www   18458 0.5 1.2 204068 25920 pts/1  S+  16:34  0:00 php father process

www   18459 0.0 0.3 204068 6656 pts/1  S+  16:34  0:00 php child process

www@iZ2zec3dge6rwz2uw4tveuZ:~$ ps -aux|grep -v "grep\|nginx\|php-fpm" | grep php

www   18458 0.0 1.2 204068 25920 pts/1  S+  16:34  0:00 php father process

www   18459 0.0 0.0   0   0 pts/1  Z+  16:34  0:00 [php] <defunct>
      

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/6038.html