PHP程序打开多次

PHP程序打开多次,php,windows,command-line-interface,proc-open,k2f,Php,Windows,Command Line Interface,Proc Open,K2f,我有一个实用函数,用于通过CLI(cmd、bash等)执行程序。它返回一个由3项组成的数组:STDOUT、STDERR和EXIT code 到目前为止,它运行良好,没有任何问题。事实上,我对它的问题并没有真正妨碍它的功能,但我关心的是性能 问题是,在某些情况下,PHP多次运行同一命令(在我的情况下是3次),即使它应该只运行一次 /** * Executes a program and waits for it to finish, taking pipes into account. * @

我有一个实用函数,用于通过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下监视并看到这种行为。我使用的是Windows7x64。这个程序是32位的,PHP也是

编辑:所讨论的程序是定制开发的,它不会打开新进程。

测试只运行一次的代码看起来有缺陷

如果有两个php进程正在运行,它们将不会共享一个静态变量。因此,您可能有同时的请求,导致此操作多次运行

其次,您应该在函数结束时将
$once
设置为false,否则将永远无法到达
die

尝试添加一些日志记录,以查看函数是否从两次调用


创建一些只运行外部应用程序的单元/压力测试。如果您看到多个进程,则说明您的应用程序有问题,而不是php代码。

这很奇怪。如果没有完整的代码,很难理解


如果您的服务器多次调用同一个页面,我认为这可能与CPU循环进程有关。PHP没有时间将静态变量设置为false,因为同时还有另一个对该方法的请求。另一种可能性是PHP无法正确隔离静态值,对该方法的不同请求可以读取不同的内存位置,直到PHP对这些值进行同步

我知道这可能不是最好的选择,但我就是这么做的。虽然这是在Linux上,但我相信有办法将其移植到Windows

我所做的是运行pgrep并检查是否已经存在这样的命令,以及它是否只是退出。 正如您所说的,您正在运行同一个命令(使用精确的参数),所以只需检查是否已经有一个命令正在运行,并分别执行act

我使用了这个命令:

$pid = shell_exec('pgrep -cfx "/* My command */"');
if ($pid > 1) return -1;

使用另一个过程工具验证观察结果。你没有提到它是什么程序(可能会自行进入子进程)。@Christian:我们如何检查它?正如你所说,你没有提到它是什么程序。马里奥完全正确;你应该听他的。对不起,我的意思是“检查过了”(为了避免混淆,我现在删除了评论)。我的意思是我用过程监视器检查了它。编辑:我确实听了他的话;)你能给我们提供一个一个的例子吗?每个例子的脚本执行时间是多少?还要确保记下执行脚本的时间。我担心,即使使用相同的输入,重复也会有所不同。您可以使用flock()之类的工具来确保它只运行一次。我在本地运行它,因此我可以看到每个会话以及进程都在打开。程序在自己调用时只运行一次。我确信我的原始陈述是正确的。@Christian-当您向函数添加日志记录时,它似乎被多次调用,还是进程本身被php windows或应用程序多次启动?@ByronWhitlock-进程本身被多次加载。注释代码确保函数只被调用一次。@Christian Scinerras:您知道静态变量
$once
对于每个进程分别存在,每个进程中可能有不同的值吗?i、 这行代码不会阻止不同进程运行您的function@sje397-但我肯定只有一个进程在运行这个函数。该代码确保每个进程只调用一次函数。