如何通过单个PHP文件在CLI中并行运行多实例get_data.php
在PHP CLI环境下并行运行多实例脚本
你可以通过两种简单的方式实现all.php中并行调用get_data.php,完全适配CLI环境,避免串行执行或占用Web资源的问题:
方法一:直接启动后台子进程(无需扩展,推荐)
这种方式利用系统Shell的后台运行机制,让每个get_data.php实例作为独立后台进程并行执行,all.php本身会快速启动所有进程后退出,不阻塞后续操作。
<?php // all.php // 循环生成1到25的参数 for ($param = 1; $param <= 25; $param++) { // 获取get_data.php的绝对路径,避免路径问题 $scriptPath = __DIR__ . '/get_data.php'; // 启动后台进程,将输出重定向到日志或/dev/null(根据需求调整) // 这里用/usr/bin/php确保CLI路径正确,若系统PATH已包含php可简化为php exec("/usr/bin/php {$scriptPath} {$param} > /var/log/get_data_{$param}.log 2>&1 &"); }
关键细节:
> /var/log/get_data_{$param}.log 2>&1:将每个实例的标准输出和错误输出写入独立日志文件,方便排查问题;如果不需要日志,可替换为> /dev/null 2>&1丢弃输出。&:让进程在后台运行,确保all.php不会等待单个实例执行完成再启动下一个。
方法二:使用PCNTL进程控制扩展(适合精细管控)
如果需要更精细地控制进程(比如限制并发数、等待所有进程完成后再退出),可以使用PHP的pcntl扩展(需确保CLI版本PHP已安装该扩展)。
<?php // all.php $totalInstances = 25; $runningPids = []; for ($param = 1; $param <= $totalInstances; $param++) { // 创建子进程 $pid = pcntl_fork(); if ($pid === -1) { die("创建子进程失败,参数:{$param}"); } elseif ($pid === 0) { // 子进程逻辑:执行目标脚本 $scriptPath = __DIR__ . '/get_data.php'; exec("/usr/bin/php {$scriptPath} {$param}"); exit(); // 子进程执行完成后必须退出,避免继续循环 } else { // 父进程记录子进程PID $runningPids[] = $pid; } } // 可选:等待所有子进程执行完成后,父进程再退出 foreach ($runningPids as $pid) { pcntl_waitpid($pid, $status); }
扩展优化:限制并发数
如果服务器性能有限,不想同时启动25个进程,可以加入并发控制逻辑,比如每次最多运行5个进程:
<?php // all.php $totalInstances = 25; $maxConcurrent = 5; $runningPids = []; for ($param = 1; $param <= $totalInstances; $param++) { // 若当前运行进程数达到上限,等待一个进程结束 while (count($runningPids) >= $maxConcurrent) { foreach ($runningPids as $key => $pid) { if (pcntl_waitpid($pid, $status, WNOHANG) === $pid) { unset($runningPids[$key]); } } usleep(100000); // 休眠0.1秒再检查 } $pid = pcntl_fork(); if ($pid === -1) { die("创建子进程失败,参数:{$param}"); } elseif ($pid === 0) { $scriptPath = __DIR__ . '/get_data.php'; exec("/usr/bin/php {$scriptPath} {$param}"); exit(); } else { $runningPids[] = $pid; } } // 等待剩余进程完成 foreach ($runningPids as $pid) { pcntl_waitpid($pid, $status); }
Cron配置
最后只需要在Cron中添加一条任务即可:
0 * * * * /usr/bin/php /path/to/all.php
内容的提问来源于stack exchange,提问作者Md. Sahadat Hossain
相关产品推荐
相关产品推荐

