PHP多进程讲解(三):僵尸进程
Q:什么是僵尸进程?
A:子进程在结束运行后,父进程未进行相应处理,就成为了僵尸进程。
僵尸进程的产生有几下几种原因:
- 父进程未 wait 子进程。
- 子进程发送信号 SIGCHLD 给父进程,但是父进程没有理睬。
- 其它原因
总之,父进程不负责的情况下,就可能会产生僵尸进程。
下面我们用代码来演示下:
<?php
$pid = pcntl_fork();
if ($pid === -1) {
exit('无法创建子进程');
} elseif ($pid > 0) {
// 父进程
$pid = getmypid();
echo "我是父进程:{$pid}\n";
// 休眠20秒
sleep(20);
echo "父进程:拜拜咯\n";
} else {
// 这里是子进程
$pid = getmypid();
echo "我是子进程:{$pid}\n";
echo "啊,作为子进程的我结束了\n";
}
代码中,父进程休眠了20秒的时间,子进程输出两句话,直接退出了。
我们执行下:
php process4.php
我是父进程:17482
我是子进程:17483
啊,作为子进程的我结束了
利用 ps aux |grep 17483
看下:
xiaoteng 17483 0.0 0.0 0 0 s000 Z+ 10:24上午 0:00.00 (php)
可以看到,PID=17483的进程状态为 Z+
也就是僵尸进程的意思。
Q:那如何避免僵尸进程的出现呢?
A:wait 子进程
<?php
$pid = pcntl_fork();
if ($pid === -1) {
exit('无法创建子进程');
} elseif ($pid > 0) {
// 父进程
$pid = getmypid();
echo "我是父进程:{$pid}\n";
pcntl_wait($status);
echo "子进程的退出代码:{$status}\n";
echo "父进程:拜拜咯\n";
} else {
// 这里是子进程
$pid = getmypid();
echo "我是子进程:{$pid}\n";
echo "啊,作为子进程的我结束了\n";
}
wait 到子进程的退出信号后,子进程就安全的退出了,释放出了资源,也就不会成为僵尸进程存在,占用系统资源。
Q:如何杀死僵尸进程呢?
A:僵尸进程无法通过kill干掉的,所以我们可以先干掉僵尸进程的父进程,让TA被1号进程接管,然后让系统会处理掉TA。
本作品采用 知识共享署名-相同方式共享 4.0 国际许可协议 进行许可。
评论已关闭