PHP CLI 模式多子进程任务处理

<?php

$total = 1000;
$num   = 100;

$per = $total / $num;

$isMaster = true;

$child = [];
$c = 1;

$t1 = microtime(true);
echo '模拟队列数据异步处理开始' . PHP_EOL;
while (true) {
    $t2 = microtime(true);
    echo "第 {$c} 次主循环开始" . PHP_EOL;
    $fork_error = false;
    for ($i = 1; $i <= $num; $i++) {
        $pid = pcntl_fork();

        if ($pid === -1) {
            $fork_error = true;
            break;
        }
        if ($pid > 0) {
            $child[] = $pid;
        } else {
            if ($pid === 0) {
                $t4 = microtime(true);
                echo "异步线程 {$i} 写入开始" . PHP_EOL;
                $child_time = time();
                $pdo        = new Pdo('mysql:host=mysql-5.7.20-v1;dbname=test', 'root', '123456', [
                    PDO::ATTR_PERSISTENT => true,
                ]);
                for ($j = 0; $j < $total; $j++) {
                    $time = microtime(true);
                    $sth  = $pdo->prepare('insert into rand(`rand`, `time`) values (:rand, :time)');
                    $sth->bindValue(':rand', $j, PDO::PARAM_INT);
                    $sth->bindValue(':time', $time, PDO::PARAM_INT);
                    $sth->execute();
                }
                $pdo = null;
                $id  = getmypid();
                $t5 = microtime(true);
                echo "异步线程 {$i} 写入结束,总耗时: " . ceil(($t5 - $t4) * 1000) . ' ms' . PHP_EOL;
                exit(0);
            }
        }
    }
    if ($fork_error) {
        continue;
    }
    while(count($child)) {
        foreach($child as $k => $pid) {
            $res = pcntl_waitpid($pid, $status, WNOHANG);
            if(-1 == $res || $res > 0) {
                unset($child[$k]);
            }
        }
    }

    $t3 = microtime(true);
    echo "第 {$c} 次主循环结束,耗时:" . ceil(($t3 - $t2) * 1000) . ' ms' . PHP_EOL;
    $c += 1;
    if($c > 10) {
        break;
    }
    sleep(3);
}
echo '模拟队列数据异步处理结束' . PHP_EOL;
本作品采用《CC 协议》,转载必须注明作者和本文链接
smithyj
杨圆建
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
讨论数量: 3

pcntl_fork 是创建了一个子进程,没有所谓多线程

5年前 评论
杨圆建

@Littlesqx 感谢指导

5年前 评论

参考我写的定时任务工具 https://gitee.com/392223903/EasyTask composer 包 底层也是多进程

4年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!