我有一个实用程序函数,用于通过CLI(cmd,bash等)执行程序。它返回包含3个项目的数组:STDOUT
,STDERR
和EXIT CODE
。
到目前为止,它一直很好地工作而没有问题。事实上,我遇到的问题并没有真正阻碍它的功能,但我关注的是性能。
问题在于,在某些情况下,PHP会多次运行相同的命令(在我的情况下为3次),即使它只应执行一次。
/**
* Executes a program and waits for it to finish, taking pipes into account.
* @param string $cmd Command line to execute, including any arguments.
* @param string $input Data for standard input.
* @param boolean $log Whether to log execution failures or not (defaults to true).
* @return array Array of "stdout", "stderr" and "return".
*/
public static function execute($cmd,$stdin=null,$log=true){
//static $once=true; if(!$once)die; $once=false;
$proc=proc_open($cmd, array(
0=>array('pipe','r'),
1=>array('pipe','w'),
2=>array('pipe','w') ), $pipes);
fwrite($pipes[0],$stdin); fclose($pipes[0]);
$stdout=stream_get_contents($pipes[1]); fclose($pipes[1]);
$stderr=stream_get_contents($pipes[2]); fclose($pipes[2]);
$return=proc_close($proc);
if($return!=0 && $log)
xlog('Error: Program execution returned failure.',$stdout,$stderr,$return);
return array( 'stdout'=>$stdout, 'stderr'=>$stderr, 'return'=>$return );
}
注意注释行(第9行)。那是为了测试。我启用它以确保目标程序只运行一次(我以为我的代码可能会以某种方式调用相同的函数)。 但即使启用该行,程序仍会运行多次。
实际上,我在我的代码中有两个位置,我正在执行相同的程序(在不同的场合)。两个命令行都是相同的。
然而,有一次,程序运行一次,而在这种情况下,PHP运行程序3次。
我一直在Process Explorer下监视并看到这种行为。我使用的是Windows 7 x64。程序是32位,PHP也一样。
编辑:相关程序是自定义开发的,不会打开新流程。
答案 0 :(得分:1)
您测试它只运行一次的代码看起来有缺陷。
如果你有2个php进程在运行,它们将不会共享一个静态变量。因此,您可能会同时发出请求,导致此操作多次运行。
其次,您应该在函数结束时将$once
设置为false,否则永远不会达到die
。
击>
尝试添加一些日志记录,以查看是否正在两次调用该函数。
创建一些只运行外部应用程序的单元/压力测试。如果您看到多个进程,那么您的应用程序就会出现错误,而不是php代码。
答案 1 :(得分:0)
很奇怪。如果没有完整的代码,很难弄明白。
如果你强调你的服务器多次调用同一页面,我最好的选择可能与CPU循环过程有关。 PHP没有时间将静态变量设置为false,因为同时还有另一个对此方法的请求。其他可能性是PHP无法正确隔离静态值,并且对此方法的不同请求可以读取不同的内存位置,直到PHP同步值。
答案 2 :(得分:0)
我知道这可能不是最好的选择,但这就是我所做的。虽然这是在Linux上,但我确信有办法将其移植到Windows。
我做了什么,是运行pgrep并检查是否已存在这样的命令,如果它只是退出。 如你所说,你正在运行相同的命令(具有确切的参数),所以只需检查是否已经有一个命令在运行并分别执行。
我使用了这个命令:
$pid = shell_exec('pgrep -cfx "/* My command */"');
if ($pid > 1) return -1;