PHP使用pcntl扩展创建多进程高效处理任务

前言

如果一个PHP脚本要处理10个任务,每个任务需要耗时1分钟,使用默认的单进程处理的话,需要耗时10分钟;但如果改成多进程的话,将这10个任务分配给10个进程处理,每个进程处理其中一个任务,则总耗时只需要1分钟,大大提高了效率。下面介绍如何使用PHP的pcntl扩展来创建多进程。

代码

<?php

$parentPid = getmypid(); // 父进程ID
$childNum = 3; // 要创建的子进程数量

echo "父进程[$parentPid]准备fork $childNum 个子进程\n";
for ($i = 0; $i < $childNum; $i++) {
    $ret = pcntl_fork();
    switch ($ret) {
        case -1:
            echo "Fork子进程[$i]失败\n";
            break;
        case 0: // 子进程要处理的逻辑
            $childPid = getmypid();
            echo "子进程[$i]已创建, pid = $childPid\n";
            sleep(60); // 使用sleep模拟任务执行
            echo "子进程[$i]已结束, pid = $childPid\n";
            exit();
        default: // 父进程要处理的逻辑,不管它,直接break
            break;
    }
}

/*
 * 循环等待所有的子进程退出
 * 当pcntl_wait函数的返回值等于0的时候,说明所有的子进程已经退出
 */
while (($pid = pcntl_wait($status)) > 0) {
    echo "子进程[$pid]已退出, status = $status\n";
}

echo "父进程已结束\n";

孤儿进程与僵尸进程

拥有父子进程的程序,如果处理不得当,就有可能会产生孤儿进程僵尸进程,先看下他们的定义:

名词定义
孤儿进程父进程已退出,而它的一个或多个子进程还在运行,那么这些子进程将成为孤儿进程。孤儿进程会被系统的init进程(pid=1)收养,init进程会成为这些子进程的新父进程。
僵尸进程子进程退出后,如果父进程还在运行,但父进程没有调用wait()waitpid(),那么该子进程将无法被父进程回收,从而成为僵尸进程。僵尸进程只能等到其父进程退出后由系统的init进程回收。

孤儿进程一般没有什么危害,因为孤儿进程退出后,init进程会回收它的相关资源。
但僵尸进程在其父进程不退出的情况下,会一直占用进程ID以及相关资源,无法释放,应尽量避免,因此在上面的PHP代码中,父进程循环调用pcntl_wait函数等到所有的子进程退出,从而避免孤儿进程和僵尸进程产生。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值