PHP多进程 - 回收子进程pcntl_wait 与 pcntl_waitpid

前面已经讲到,当父进程是一个常驻进程的时候,子进程退出了,父进程没有回收它,那么该子进程会成为僵尸进程,且必须等到父进程退出了才会被销毁。所以,如果父进程只是个短暂的进程,那么也没必要去回收子进程,当然主动回收更好。

PHP中父进程回收子进程的函数有两个
1、pcntl_waitpid

pcntl_waitpid ( int $pid , int &$status [, int $options = 0 ] ) : int

在这里插入图片描述
2、pcntl_wait

pcntl_wait ( int &$status [, int $options = 0 ] ) : int

这个函数等同于 pid = -1 时的 pcntl_waitpid 函数。

共同的参数:
在这里插入图片描述
$options 取值 0,WNOHANG,WUNTRACED,WNOHANG | WUNTRACED
其中 WNOHANG 是非阻塞的,但是你需要定时轮训。

本质上这两个函数的功能是一样的。

此函数挂起当前进程的执行直到一个子进程退出,或接收到一个信号要求中断当前进程,或调用一个信号处理函数。 如果一个子进程在调用此函数时已经退出(俗称僵尸进程),此函数立刻返回。子进程使用的所有系统资源将被释放。

综上所述,这两个函数都是很鸡肋的,如果是个多进程服务,类似于swoole这种,那么是肯定要去回收子进程的,但是不管是阻塞还是定时轮训的方式,主进程都很难分身去做别的事情。

所以,这种回收子进程的方式,只适合做临时的多任务的处理,或者类似于 exec 函数这种阻塞式的场景,下面简单给个例子。

function main()
{
    $count = 6;
    for ($i = 1; $i <= $count; $i++) {
        $pid = pcntl_fork();
        if ($pid > 0) {

        } else if (0 == $pid) {
            task($i);
            exit; // 一定要退出,否则子进程会继承上下文继续执行
        } else {
            echo "fork失败" . PHP_EOL;
        }
    }

    while ($count) {
        $pid = pcntl_wait($result);
        var_dump($pid);
        var_dump($result);
        $count--;
    }
}

function task($taskId)
{
    echo "task {$taskId} is over", PHP_EOL;
}

main();

在这里插入图片描述
查看是否有僵尸进程
在这里插入图片描述
模拟出现僵尸进程

function main()
{
    $count = 6;
    for ($i = 1; $i <= $count; $i++) {
        $pid = pcntl_fork();
        if ($pid > 0) {

        } else if (0 == $pid) {
            task($i);
            exit; // 一定要退出,否则子进程会继承上下文继续执行
        } else {
            echo "fork失败" . PHP_EOL;
        }
    }

    sleep(10);// 会出现僵尸进程

    while ($count) {
        $pid = pcntl_wait($result);
        var_dump($pid);
        var_dump($result);
        $count--;
    }
}

function task($taskId)
{
    echo "task {$taskId} is over", PHP_EOL;
}

main();

运行程序后立马查看僵尸进程
在这里插入图片描述
等程序结束后,再查看僵尸进程,发现已经没有了。

至于 pcntl_waitpid 的例子就不写了,是一样的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值