PHP-proc_get_status';运行';javaw可执行文件仍在运行时返回false
我正在用一个无限循环的java文件执行javaw,使用以下命令:PHP-proc_get_status';运行';javaw可执行文件仍在运行时返回false,php,proc-open,Php,Proc Open,我正在用一个无限循环的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 t
$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']);
}
第一次迭代/休眠后(1):
数组(8){
[“command”]=>string(157)“java-cp”。/完全多样化的集合序列“SuperEasyProblemSolution2/dev/null 2>&1int(3264)
[“正在运行”]=>bool(false)
[“已发信号”]=>bool(假)
[“已停止”]=>bool(false)
[“exitcode”]=>int(1)
[“termsig”]=>int(0)
[“stopsig”]=>int(0)
}
进程在超时之前退出
测试后,$status['pid']似乎与Windows“资源监视器”下javaw.exe的pid不同。如果Java应用程序作为守护程序运行,那么它将具有不同的pid Java应用程序是否尝试输出任何内容?如果是这样,那么您没有读取管道,因此脚本最终将填充缓冲区并挂起(这可能导致Java停止运行) 如果您不关心输出,请将其发送到
/dev/null
以消除它:
/cmd/to/run > /dev/null 2>&1
如果您选择从管道中读取数据,则如果没有数据,则读取函数将阻塞-以绕过您可能要使用的数据:
stream_set_blocking($pipes[0], 0)
这将关闭阻塞模式(如果没有数据等待,读取功能将立即返回
FALSE
。由于您提到您在windows上执行此操作,我意识到发生了什么-
javaw(带W)作为windows应用程序启动它并立即返回(这就是为什么running=false)
您需要使用java(不带w)在控制台中运行它
java = console application
javaw = windows application with no console
虽然我们无法确定proc_get_status返回不正确的布尔值的问题,但是我们能够找到一个很好的解决方法(对于Unix),使用
if(文件_存在(“/proc/”$status[“pid”])){
//进程仍在运行
}
检查进程是否仍在运行
以下是完整的代码摘录:
$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;
}
}
$proc=proc_open($javaCmd,数组(数组(“管道”、“r”)、数组(“管道”、“w”)、数组(“管道”、“w”)、$pipes);
$status=proc\u get\u status($proc);
如果($status[“pid”]==false)
{
//进程未正确执行
}
其他的
{
$timeOut=0;
$forceKill=true;
而($timeOut<$timeLimit)
{
$timeOut++;
睡眠(1);
echo“Timeout位于“.$Timeout.”和timelimit:“.$timelimit.”
;
如果(文件_存在(“/proc/”$status[“pid”])){
//进程仍在运行
}
其他的
{
echo“在“.$timeOut.”秒后完成运行
;
$forceKill=false;
打破
}
}
如果($forceKill==true)
{
回显“手动清除pid”。$状态['pid'];
exec(“sudo kill”。$status['pid']);
$runTime=$timeLimit;
}
}
请打印出两个结果的$status
我已经发布了$status var\u dump一件我在辅助本地设备上测试时注意到的事情,java可执行文件没有显示在任务管理器中,而是显示在资源管理器中。在那里,它的PID为7600,而proc_get_status报告的PID为1096。我不关心输出-我只想确保它在特定的时间限制内运行。我尝试使用/dev/null
和流设置阻塞($pipes[0],0)
,但都不起作用。我在windows上运行,它可能是作为守护进程运行的。如果你把你的代码放在一个.bat文件中,并从命令行调用它会怎么样?我使用linux,所以我猜测windows是如何处理它的——但也许它返回的是重定向管道(proc_get_status
的替代方案,我在java和javaw中都遇到了这个问题(我第一次使用java,然后尝试了javaw,我又回到了java)。我在检查/proc/$pid时取得了一些成功,因此我可能会放弃windows解决方案而坚持使用unix。
java = console application
javaw = windows application with no console
$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;
}
}