Gan*_*h S 5 java timeout process processbuilder
参考代码 :
ProcessBuilder ps4;
Process pr4 = null;
String batchFile3 = new File(path + "/src/example.sh");
ps4 = new ProcessBuilder(batchFile3.getAbsolutePath());
ps4.redirectErrorStream(true);
ps4.directory(new File(path + "/src/"));
pr4 = ps4.start();
BufferedReade readRun = new BufferedReader(new InputStreamReader(pr4.getInputStream()));
if(pr4.waitFor()==0)
{
}
String line,stre;
while ((line = readRun.readLine()) != null) {
System.out.print("-----" + line);
if (line != null) {
stre += line;
}
}
Run Code Online (Sandbox Code Playgroud)
在这里我得到了stre字符串,它可能是错误或由我正在执行的批处理文件生成的输出.
我想停止批处理文件的执行,如果需要花费4-5秒来执行批处理文件执行过程.
同样在这种情况下,我应该能够返回程序来处理一个块,只有在处理批处理文件的这种延迟发生时,才会执行该块,否则不应该处理该块.
dim*_*414 13
据我了解,如果运行时间超过四或五秒,您希望停止子进程.这不能直接使用ProcessBuilder
(您可以看到类中不存在相关方法),但是一旦子进程开始,您就可以轻松地实现此行为.
Process.waitFor()
在示例代码中调用是有问题的,因为它将无限期地阻止当前线程 - 如果您的进程花费超过五秒钟.waitFor()
将不会停止它.但是.waitFor()
过载,其兄弟姐妹需要一个timeout
说法.
Run Code Online (Sandbox Code Playgroud)public boolean waitFor(long timeout, TimeUnit unit) throws InterruptedException
如果需要,使当前线程等待,直到此Process对象表示的子进程终止,或者指定的等待时间过去.
Process.destroy()
如果花费的时间太长,您可以同时使用它来停止该过程.例如:
Process process = new ProcessBuilder(command, and, arguments)
.redirectErrorStream(true)
.directory(workingDir)
.start();
process.waitFor(5, TimeUnit.SECONDS);
process.destroy();
process.waitFor(); // wait for the process to terminate
Run Code Online (Sandbox Code Playgroud)
这依赖于在Process.destroy()
已经完成的子进程上调用时无操作的事实.在Java 9之前,没有记录这种行为,但在实践中始终如此.另一种方法是检查返回值.waitFor()
,但这会引入TOCTTOU竞赛.
怎么样Process.destroyForcibly()
?一般来说,你不应该调用这种方法(JDK可能更清楚的另一件事),但是如果一个进程真正挂起,它可能就变得必要了.理想情况下,您应该确保您的子流程表现良好,但如果您必须使用.destroyForcibly()
这个,我建议您这样做:
// Option 2
process.waitFor(5, TimeUnit.SECONDS); // let the process run for 5 seconds
process.destroy(); // tell the process to stop
process.waitFor(10, TimeUnit.SECONDS); // give it a chance to stop
process.destroyForcibly(); // tell the OS to kill the process
process.waitFor(); // the process is now dead
Run Code Online (Sandbox Code Playgroud)
这确保了行为不当的过程将被迅速杀死,同时仍然给予正确实施的程序在被指示时退出的时间.的确切行为.destroy()
和.destroyForcibly()
具体的操作系统,但在Linux上我们可以看到,它们对应于SIGTERM
和SIGKILL
:
int sig = (force == JNI_TRUE) ? SIGKILL : SIGTERM;
kill(pid, sig);
Run Code Online (Sandbox Code Playgroud)
您应该很少需要打电话.destroyForcibly()
,如果您发现有必要,我建议您只添加它.
选项2在概念上类似于使用如下timeout
命令:
$ timeout --kill-after=10 5 your_command
Run Code Online (Sandbox Code Playgroud)
Process.waitFor(long, TimeUnit)
在Java 7中复制很容易,默认的Java 8实现没有什么神奇之处:
public boolean waitFor(long timeout, TimeUnit unit)
throws InterruptedException
{
long startTime = System.nanoTime();
long rem = unit.toNanos(timeout);
do {
try {
exitValue();
return true;
} catch(IllegalThreadStateException ex) {
if (rem > 0)
Thread.sleep(
Math.min(TimeUnit.NANOSECONDS.toMillis(rem) + 1, 100));
}
rem = unit.toNanos(timeout) - (System.nanoTime() - startTime);
} while (rem > 0);
return false;
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
7427 次 |
最近记录: |