0

私はこれを使用して無限ループのJavaファイルでjavawを実行しています:

$descriptorspec = array(
                                0 => array("pipe", "r"),  // stdin is a pipe that the child will read from
                                1 => array("pipe", "w"),  // stdout is a pipe that the child will write to
                                2 => array("pipe", "w") // stderr is a file to write to
                        );

 // e.x. $javaCmd = "java -cp "../Fully Diversified Sequences of Sets" SuperEasyProblemSolution2 > /dev/null 2>&1 < h.in"
$proc = proc_open($javaCmd, $descriptorspec, $pipes);//, $cwd, $env);
 stream_set_blocking($pipes[0], 0) ;

 $status = proc_get_status($proc);  
 var_dump($status);
  $timeOut = 5;
  $currentSecond = 0;

  while( $currentSecond < $timeOut ) {
        echo '<br/>';
        sleep(1);
        $currentSecond = $currentSecond +1;
        if( ! $status["running"] )
        {
            echo 'process exited before timing out'; // Process must have exited, success!
            return;
        }
        $status = proc_get_status($proc);
        var_dump($status);
  } // end while
  if($currentSecond  == $timeOut)
  {
      // kill KILL KILL!
      exec("taskkill /PID ".$status['pid']);
  }

への最初の呼び出しでproc_get_statusrunning属性はtrueを返します。への2回目の呼び出し(1秒後)でproc_get_statusfalserunningを返します。ただし、アプリケーションjavaw.exeはまだ実行中です(whileループを呼び出して、最終的にタイムアウトします)。proc_get_status

私の目標は、タイムアウトの期限が切れた後にプログラムをタスクキルすることです。ここで同様の質問を参照してください。Win7 64ビット、PHP5.3で実行しています

上のVarダンプ$status:(注;私は適用しようとしましstream_set_blocking($pipes[0], 0) ;た、同じ問題)

タイムアウトループに入る前:

    array(8) { 
["command"]=> string(157) "java -cp "../Fully Diversified Sequences of Sets" SuperEasyProblemSolution2 /dev/null 2>&1 < h.in" 
["pid"]=> int(3264) 
["running"]=> bool(true) 
["signaled"]=> bool(false) 
["stopped"]=> bool(false) 
["exitcode"]=> int(-1) 
["termsig"]=> int(0) 
["stopsig"]=> int(0) 
} 

最初の反復/sleep(1)後:

    array(8) { 
["command"]=> string(157) "java -cp "../Fully Diversified Sequences of Sets" SuperEasyProblemSolution2 /dev/null 2>&1 < h.in" 
["pid"]=> int(3264) 
["running"]=> bool(false) 
["signaled"]=> bool(false) 
["stopped"]=> bool(false) 
["exitcode"]=> int(1) 
["termsig"]=> int(0) 
["stopsig"]=> int(0) 
} 
    process exited before timing out

テスト後、$status['pid']はWindowsのリソースモニターでのjavaw.exeのpidとは異なるようです。

4

3 に答える 3

1

Javaアプリがデーモンとして実行されている場合、PIDは異なります。

Javaアプリは何かを出力しようとしますか?もしそうなら-あなたはパイプを読んでいないので、スクリプトは最終的にバッファをいっぱいにしてハングします(これによりJavaの実行が停止する可能性があります)

出力を気にしない場合は、それをに送信して/dev/null削除します。

/cmd/to/run > /dev/null 2>&1

パイプからデータを読み取ることを選択した場合、データがない場合は読み取り関数がブロックされます。これを回避するには、次のようにします。

stream_set_blocking($pipes[0], 0)

これにより、ブロッキングモードがオフになります(FALSE待機中のデータがない場合、読み取り機能はすぐに戻ります)。

于 2012-08-28T18:56:04.497 に答える
1

proc_get_statusが誤ったブール値を返す問題を特定することはできませんでしたが、(Unixの場合)適切な回避策を見つけることができました。

if (file_exists("/proc/".$status["pid"])) { // process still running }

プロセスがまだ実行されているかどうかを確認します。

完全なコードの抜粋は次のとおりです。

$proc = proc_open($javaCmd, array(array("pipe", "r"), array("pipe", "w"), array("pipe", "w")), $pipes);

$status = proc_get_status($proc);

if($status["pid"] === false)
{
    // Process did not execute correctly
}
else
{
        $timeOut = 0;
        $forceKill = true;

        while($timeOut < $timeLimit)
        {
            $timeOut++;
            sleep(1);
            echo 'Timeout is at '.$timeOut.' and timelimit: '.$timeLimit.'<br/>';

            if (file_exists("/proc/".$status["pid"])) {
            // process still running
            }
            else
            {
                echo 'Finished running after '.$timeOut.' seconds<br/>';
                $forceKill = false;
                break;
            }

        }
        if($forceKill == true)
        {
            echo ' Manual killing pid '.$status['pid'];
            exec("sudo kill ".$status['pid']);
            $runTime = $timeLimit;
        }


}
于 2012-08-30T23:06:51.657 に答える
0

あなたがウィンドウズでこれをしていると言ったので、私は何が起こっているのか気づきました-

javaw(W付き)はWindowsアプリとして起動し、すぐに戻ります(これがrunning = falseである理由です)

コンソールで実行するには、java(wなし)を使用する必要があります。

java = console application
javaw = windows application with no console
于 2012-08-30T22:47:10.037 に答える