修改第三个案例的代码,但是,我们并不添加WNOHANG,演示说明pcntl_waitpid()功能:
$pid = pcntl_fork();
if ($pid > 0) {
// 下面这个函数可以更改php进程的名称
cli_set_process_title('php father process');
// 返回值保存在$wait_result中
// $pid参数表示 子进程的进程ID
// 子进程状态则保存在了参数$status中
// 将第三个option参数设置为常量WNOHANG,则可以避免主进程阻塞挂起,此处父进程将立即返回继续往下执行剩下的代码
$wait_result = pcntl_waitpid($pid, $status);
var_dump($wait_result);
var_dump($status);
// 让主进程休息60秒钟
sleep(60);
} else if (0 == $pid) {
cli_set_process_title('php child process');
// 让子进程休息10秒钟,但是进程结束后,父进程不对子进程做任何处理工作,这样这个子进程就会变成僵尸进程
sleep(10);
} else {
exit('fork error.' . PHP_EOL);
}
下面是运行结果,一个执行php zombie3.php 程序的终端窗口
www@iZ2zec3dge6rwz2uw4tveuZ:~/test$ php zombie3.php int(18586) int(0) ^C
ctrl-c 发送 SIGINT 信号给前台进程组中的所有进程。常用于终止正在运行的程序。
下面是ps -aux终端窗口
www@iZ2zec3dge6rwz2uw4tveuZ:~$ ps -aux|grep -v "grep\|nginx\|php-fpm" | grep php www 18605 0.3 1.2 204068 25756 pts/1 S+ 16:52 0:00 php father process www 18606 0.0 0.3 204068 6636 pts/1 S+ 16:52 0:00 php child process www@iZ2zec3dge6rwz2uw4tveuZ:~$ ps -aux|grep -v "grep\|nginx\|php-fpm" | grep php www 18605 0.1 1.2 204068 25756 pts/1 S+ 16:52 0:00 php father process www@iZ2zec3dge6rwz2uw4tveuZ:~$ ps -aux|grep -v "grep\|nginx\|php-fpm" | grep php www 18605 0.0 1.2 204068 25756 pts/1 S+ 16:52 0:00 php father process www@iZ2zec3dge6rwz2uw4tveuZ:~$ ps -aux|grep -v "grep\|nginx\|php-fpm" | grep php // ctrl-c 后不再被阻塞 www@iZ2zec3dge6rwz2uw4tveuZ:~$
实际上可以看到主进程是被阻塞的,一直到第十秒子进程退出了,父进程不再阻塞
修改第四段代码,添加第三个参数WNOHANG,代码如下:
$pid = pcntl_fork();
if ($pid > 0) {
// 下面这个函数可以更改php进程的名称
cli_set_process_title('php father process');
// 返回值保存在$wait_result中
// $pid参数表示 子进程的进程ID
// 子进程状态则保存在了参数$status中
// 将第三个option参数设置为常量WNOHANG,则可以避免主进程阻塞挂起,此处父进程将立即返回继续往下执行剩下的代码
$wait_result = pcntl_waitpid($pid, $status, WNOHANG);
var_dump($wait_result);
var_dump($status);
echo "不阻塞,运行到这里" . PHP_EOL;
// 让主进程休息60秒钟
sleep(60);
} else if (0 == $pid) {
cli_set_process_title('php child process');
// 让子进程休息10秒钟,但是进程结束后,父进程不对子进程做任何处理工作,这样这个子进程就会变成僵尸进程
sleep(10);
} else {
exit('fork error.' . PHP_EOL);
}
内容版权声明:除非注明,否则皆为本站原创文章。
