【问题标题】:Call Java from PHP with timeout handler使用超时处理程序从 PHP 调用 Java
【发布时间】:2012-08-15 06:31:12
【问题描述】:

问题:我正在通过用户提交的 PHP 运行 java 文件。 java 文件有可能导致无限循环。在php执行过程中如何处理?

这是我的代码:

$proc = proc_open($javaCmd, array(array("pipe", "r"), array("pipe", "w"), array("pipe", "w")), $pipes);
// Check status here logic ?
proc_close($proc);

它目前正在等待进程完成,但我希望它在 30 秒或一分钟后超时。我试过set_time_limit(x),但这并没有终止java.exe

我的问题是,我是否可以在 X 秒后检查 java.exe 进程的状态,如果它仍在运行则终止?或者,我是否需要在java中使用timeout functionality(即有一个在线程上执行用户提交的类的主类)

【问题讨论】:

    标签: java php unix timeout


    【解决方案1】:

    是的,这是可能的。在这方面,我认为 java 进程与任何其他进程没有什么不同。请参阅unix exec with timeoutwindows exec with timeout 的这些链接。

    这段代码不是我写的,这里是复制粘贴的,以防原件从网上消失:

    对于 unix:

    <?php
      function PsExecute($command, $timeout = 60, $sleep = 2) {
            // First, execute the process, get the process ID
    
            $pid = PsExec($command);
    
            if( $pid === false )
                return false;
    
            $cur = 0;
            // Second, loop for $timeout seconds checking if process is running
            while( $cur < $timeout ) {
                sleep($sleep);
                $cur += $sleep;
                // If process is no longer running, return true;
    
               echo "\n ---- $cur ------ \n";
    
                if( !PsExists($pid) )
                    return true; // Process must have exited, success!
            }
    
            // If process is still running after timeout, kill the process and return false
            PsKill($pid);
            return false;
        }
    
        function PsExec($commandJob) {
    
            $command = $commandJob.' > /dev/null 2>&1 & echo $!';
            exec($command ,$op);
            $pid = (int)$op[0];
    
            if($pid!="") return $pid;
    
            return false;
        }
    
        function PsExists($pid) {
    
            exec("ps ax | grep $pid 2>&1", $output);
    
            while( list(,$row) = each($output) ) {
    
                    $row_array = explode(" ", $row);
                    $check_pid = $row_array[0];
    
                    if($pid == $check_pid) {
                            return true;
                    }
    
            }
    
            return false;
        }
    
        function PsKill($pid) {
            exec("kill -9 $pid", $output);
        }
    

    对于窗户:

    <?php
    // pstools.inc.php
    
        function PsExecute($command, $timeout = 60, $sleep = 2) {
            // First, execute the process, get the process ID
            $pid = PsExec($command);
    
            if( $pid === false )
                return false;
    
            $cur = 0;
            // Second, loop for $timeout seconds checking if process is running
            while( $cur < $timeout ) {
                sleep($sleep);
                $cur += $sleep;
                // If process is no longer running, return true;
                if( !PsExists($pid) )
                    return true; // Process must have exited, success!
            }
    
            // If process is still running after timeout, kill the process and return false
            PsKill($pid);
            return false;
        }
    
        function PsExec($command) {
            exec( dirname(__FILE__). "\\psexec.exe -s -d $command  2>&1", $output);
    
            while( list(,$row) = each($output) ) {
                $found = stripos($row, 'with process ID ');
                if( $found )
                    return substr($row, $found, strlen($row)-$found-strlen('with process ID ')-1); // chop off last character '.' from line
            }
    
            return false;
        }
    
        function PsExists($pid) {
            exec( dirname(__FILE__). "\\pslist.exe $pid 2>&1", $output);
    
            while( list(,$row) = each($output) ) {
                $found = stristr($row, "process $pid was not found");
                if( $found !== false )
                    return false;
            }
    
            return true;
        }
    
        function PsKill($pid) {
            exec( dirname(__FILE__). "\\pskill.exe $pid", $output);
        }
    

    【讨论】:

    • 谢谢!我会试试这个并发布我的结果
    • 我完全为 Windows 复制了代码,但每次 $pid 都返回 false。如果我删除它,它会运行超时时间,并按预期终止进程。
    • @le_garry 我真的不明白这是怎么回事,因为如果它返回 false,它就没有 pid 来杀死进程。但是如果删除时它按预期工作,我想没关系,那么...... :)
    • 是的,对我来说也没有意义,也许 pskill 有一个 kill-all-pstools 功能被触发,因为 $pid 肯定是 === false。
    • 如果你不想调试它为什么是假的,你可能想要分解 PsExec() 函数并以更小的步骤调试它 - 它解析输出很大程度上取决于小细节,因此在不同的设置和操作系统版本下非常脆弱。
    猜你喜欢
    • 2019-08-16
    • 1970-01-01
    • 2017-01-30
    • 1970-01-01
    • 2021-07-02
    • 1970-01-01
    • 2011-09-20
    • 1970-01-01
    • 2011-09-19
    相关资源
    最近更新 更多