我已经阅读了关于SO的其他问题并且标题相似,但这不是这个问题的内容.我知道如何从另一个PHP脚本执行PHP脚本.问题是,当我这样做时,它使用了太多的CPU.我想知道如何减少这一点.
我有一个简单的类似前端控制器的脚本叫做index.php.它处理来自客户端的GET请求,并根据传递的“action”参数,将请求发送到适当的文件来处理它.例如,这是客户端请求:
xhttp.open("GET", serverURL + "?action=doSomething" + "&userID=" + user.ID + "&time=" + lastServerTime, true);
index.php有一个数组,它将“action”参数映射到适当的文件:
exec('php ' . $url_map[$action] . ' "' . $parameter1 . '"' . ' "' . $parameter2 . '" 2>&1', $output, $return_value);
出于测试目的,我创建了一个PHP脚本,除了测量CPU利用率并将其转储到日志文件之外什么都不做:
function varDumpToFile($parameter1) {
$file = 'log.txt';
$dump = $parameter1;
$output = print_r($dump, true);
file_put_contents($file, $output, FILE_APPEND | LOCK_EX);
}
varDumpToFile(`ps -eo pcpu,pid,user,args --no-headers| sort -t. -nk1,2 -k4,4 -r |head -n 5`);
?>
这会生成一个如下所示的日志文件:
9.0 3123052 user /opt/cpanel/ea-php56/root/usr/bin/php cputest.php 10 147424 1537625595
显然,PHP脚本不应占用9%的CPU来执行.为了比较,我运行相同的脚本通过GET请求直接访问它:
0.1 3186198 user lsphp:ic_html/dev/php/cputest.php
0.1%更像是它.但是为什么从另一个PHP脚本调用这个PHP脚本会占用这么多CPU?是因为当我执行PHP时,我必须执行PHP的“新实例”,这有很多开销吗?如果是这样,有没有办法使用“已经运行”的PHP实例来执行PHP脚本?还是有另一种方法吗?
解决方法:
我总是说“如有疑问,请查看PHP源代码”.例如In here.在执行exec时,您必须分叉进程,创建新流,从输入缓冲区读取等.
而且,虽然PHP是一种编译语言,但对于新分叉的进程,您必须运行操作码编译器以生成操作码(类似于Java字节码的指令),然后执行这些操作.你可以阅读所有关于它的内容here.最后你运行编译器两次,分别为每个fork.
它值9%的CPU吗?我不知道.也许.也许不吧.谁知道.
“更好的解决方案”?升级到最新版本的PHP. PHP 5.6不再受支持,安全更新将在3个月内停止.更好的解决方案 – 在不使用exec的情况下保持正常的面向对象和可维护的代码. IMO,可以像你一样和exec一起玩.但如果这是你的生产代码,我会为那些将你的代码保留下来的人的灵魂祈祷.
标签:php,exec
来源: https://codeday.me/bug/20190527/1161779.html