PHP-多进程复习

场景:统计从1月份到3月份,每一天的商品数量。

// 开始日期
$startDate = '2022-01-01';
// 结束日期
$endDate = '2022-03-31';

// 当前统计的日期 (从开始日期开始统计)
$currentDate = $startDate;

// 用于记录子进程id的容器
$childrenIds = [];

// 直到计算日期超过结束日期结束
while(strtotime($currentDate) <= strtotime($endDate)) {

    // A: 从这里开始, 得到进程id
    $pid = pcntl_fork();
    
    // 从调用pcntl_fork()时, 系统会复制一份所有的代码, 分别给主进程和进程同时执行
    // 那子进程从哪里开始执行? 从pcntl_fork() 开始往下执行
    // 那父子进程的变量如$startDate, $endDate也是共享一样的吗, 是一样,因为是复制
    // 那父子进程的变量修改,相互影响吗? 因为两个作用于不一样,所以还是要看是否按引用传递
    
    if ($pid == -1) {
        die('进程fork失败');
    } elseif ($pid == 0) {
        // B: 如果当前执行的是子进程, 由于不是父进程,所以拿到的$pid = 0, 所以由子进程执行sum统计操作
        $this->sum($currentDate);
        // 子进程仅负责统计, 不需要走下面的操作, 下面操作交给父进程处理
        die();
    } else {
        // C: 父进程会拿到子进程的$pid, 所以 $pid > 0
        $childrenIds[$pid] = $pid;

        //  下个子进程的统计日期是+1天
        $currentDate = date('Y-m-d', strtotime($currentDate.' +1 day'));
        
        // D: 为了防止创建太多的子进程,父进程控制一下子进程数量
        if (count($childrenIds) > 3) {
            // 父进程先阻塞一下不动, 让已经创建的子进程统计完,再进行下次循环(走A的操作,创建新的子进程)
            $childrenId = pcntl_wait($status);
            // 减少子进程数量, 方便父进程执行到D那一窜代码,控制子进程数量
            unset($childrenIds[$childrenId])
        }
    }
}

// 1. 下面的代码由于上面的while父进程没有die, 因此下面的代码都是在父进程执行
// 2. 所以这就为什么在while中子进程执行完统计,就需要die, 防止子进程执行了父进程的代码
// 3. 由于在上面while中,父进程控制子进程的数量超过3个才让子进程继续跑完,因此下面的代码是让剩余的3个子进程也要跑完,父进程确保所有子进程都跑完。

while(count($childrenIds) > 0) {
  $childrenId = pcntl_wait($status);
  unset($childrenIds[$childrenId])
}

注意地方:由于父子进程状态是一样的,所以子进程最好都需要重置一下数据库连接,redis连接,rabbitmq连接等

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值