PHP 多进程(fork)

PHP 多进程(fork)

背景

近期接触到一个项目,里面用到php脚本,脚本里使用并发处理数据,运行时发现内存超限,定位到时并发开太多进程,导致内存拷贝,触发内存超限。然后就想改进处理逻辑,控制并发量或者解决内存拷贝问题,因时间紧急,所以选择控制并发量,先把脚本跑起来,但之前接触php并发场景较少,一时无从下手,特此记录php并发控制的小示例。

函数说明

后续示例会用到两个进程并发相关的函数:pcntl_fork、pcntl_wait

pcntl_fork

官方文档:https://www.php.net/manual/zh/function.pcntl-fork.php

在当前进程当前位置产生分支(子进程)。译注:fork是创建了一个子进程,父进程和子进程都从fork的位置开始向下继续执行,不同的是父进程执行过程中,得到的fork返回值为子进程 号,而子进程得到的是0,fork返回值为-1表示开启失败。

pcntl_wait

官方文档:https://www.php.net/manual/zh/function.pcntl-wait.php

示例代码

<?php

const TASK_NUM = 10;   // 任务数
const MAX_PROCESS = 3; // 最大进程数量,并发控制

$running = 0; // 记录正在运行的子进程数
for ($i = 0; $i < TASK_NUM; $i++) {
    $pid = pcntl_fork(); // 开启新进程

    if ($pid == -1) {
        die("could not fork"); // 开启失败
    } elseif ($pid) {
        // 父进程逻辑
        $running++; // 进程数+1
        if ($running >= MAX_PROCESS) { // 子进程开启数量达到上限
            pcntl_wait($status); // 等待有子进程退出
            $running--; // 有子进程退出,进程数-1
        }
    } else {
        // 子进程逻辑
        $ss = rand(1, 20);
        echo "child:$i, sleep $ss second... \n";
        sleep($ss);
        echo "child:$i, finish sleep.\n";
        exit(0); // 子进程逻辑结束,注意退出点
    }
}

// 等待所有子进程都结束
while ($running) {
    pcntl_wait($status);
    $running--;
}
echo "done.\n\n";

运行结果示例

wangyuanyuan14@B000000137984L php % php index.php
child:1, sleep 2 second...
child:0, sleep 20 second...
child:2, sleep 1 second...
child:2, finish sleep.
child:3, sleep 12 second...
child:1, finish sleep.
child:4, sleep 16 second...
child:3, finish sleep.
child:5, sleep 6 second...
child:4, finish sleep.
child:6, sleep 10 second...
child:5, finish sleep.
child:7, sleep 17 second...
child:0, finish sleep.
child:8, sleep 18 second...
child:6, finish sleep.
child:9, sleep 10 second...
child:7, finish sleep.
child:8, finish sleep.
child:9, finish sleep.
done.

wangyuanyuan14@B000000137984L php % 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值