捕获执行时间,如果执行时间太长,则移动到下一个元素


Capture execution time and move to next element if execution is too long

我只是想知道是否有可能检测运行脚本的当前执行时间,我正在创建一个应用程序来ping网络上的一些计算机。因为这是在Linux机器上完成的,所以ping系统与Windows不同。

在linux机器上,如果计算机关闭,那么服务器将在发出ping命令后挂起主消息,并且没有任何更多的输出。将只是挂起(以我对linux ping的经验)

所以我有这个脚本:
$Computer_Array = array( 
  "Managers" => "192.168.0.5",
  "Domain Controller" => "192.168.0.1"
  "Proxy Controller" => "192.168.0.214"
);
foreach ($Computer_Array AS $Addresses){ 
  exec('ping'.$Addresses, $Output);
}

稍后将用于显示统计信息。现在的问题是,由于经理的计算机在发出ping命令时受到onoff等电源条件的影响,只是挂起了。所以我想知道是否有一种方法来捕获当前执行函数的microtime();,如果它超过阈值,那么移动到下一个元素。我宁愿将其保留为核心PHP,但如果这样的解决方案只能通过AJAX或其他语言完成,那么我将不得不咨询开发人员是否可以集成外部方法。

ping命令允许您指定在放弃之前等待多长时间:

ping -c 5 -t 1 127.0.0.2

无论发送了多少个ping,它都会在一秒后返回。具体的命令行参数会因平台而异。

或者,如果您可以使用pcntl,请查看pcntl_alarm();它会在一定的时间后将SIGALRM信号传递给您的应用程序,该时间可以被捕获。

最后,我自己还没有测试过,你可以尝试使用proc_open()stream_select()在一个管道上;如果在一段时间后管道上没有发生任何事情,那么可以终止该进程。

如果你想在PHP中这样做,或者遇到类似的问题,这里有一个使用PHP代码执行后台进程的示例

PHP脚本需要对输出文件有写权限。这个概念基本上适用于任何情况,从ping到其他PHP脚本。

function isRunning($pid){
    try{
        $result = shell_exec(sprintf("ps %d", $pid));
        if( count(preg_split("/'n/", $result)) > 2){
            return true;
        }
    }catch(Exception $e){}
    return false;
}
$cmd = "ping 127.0.0.1";
$outputfile = "output";
$pidfile = "pid";
$start = microtime(true);
// Don't last longer than 10 seconds
$threshold = 2;
// Ping and get pid
exec(sprintf("%s > %s 2>&1 & echo $! > %s", $cmd, $outputfile, $pidfile));
$pid = `tail -n 1 $pidfile`;
// Let the process run until you want to stop it
while (isRunning($pid)){
    // Check output here...
    if ((microtime(true)-$start) > $threshold){
        $o = `kill $pid`;
        die("Timed out.");
    }
}

$end = microtime(true);
$time = $end - $start;
echo "Finished in $time seconds'n";