[英]Check if process is running on windows/linux
我有一个过程
Runtime rt = Runtime.getRuntime() ;
Process p = rt.exec(filebase+port+"/hlds.exe +ip "+ip+" +maxplayers "+players+ " -game cstrike -console +port "+port+" -nojoy -noipx -heapsize 250000 +map de_dust2 +servercfgfile server.cfg +lservercfgfile +mapcyclefile mapcycle.txt +motdfile motd.txt +logsdir logs -zone 2048",null, new File(filebase+port)) ;
我想检查这个进程是在运行还是在崩溃的情况下崩溃想要重新启动它,这个进程可以有多个实例可用,具体取决于端口
我可以在 Linux 和 Windows 上跟踪这个东西吗? 阅读一些关于它的文章,但这 1 篇有点不同,因为它涉及多次出现并且只需要检查某个特定过程
boolean isRunning(Process process) {
try {
process.exitValue();
return false;
} catch (Exception e) {
return true;
}
}
请参阅http://docs.oracle.com/javase/6/docs/api/java/lang/Process.html#exitValue()
您可以执行p.waitFor()
以便执行该语句的线程等待该过程完成。 然后您可以立即执行清理/重新启动逻辑,因为该代码将在进程终止时执行。 但是,如果进程挂起而不是死亡,我不确定这将如何工作,但这可能值得一试。 顺便说一句,如果这是您要在生产中执行的操作,我建议您在这种情况下使用Java Service Wrapper和supervisord
。
从 Java 8 开始,您可以执行以下操作:
对于 Java 8 之前的代码,我使用反射和回退来捕获IllegalThreadStateException
。 反射仅适用于ProcessImpl
实例,但由于这是ProcessBuilder
返回的内容,因此对我来说通常是这种情况。
public static boolean isProcessIsAlive(@Nullable Process process) {
if (process == null) {
return false;
}
// XXX replace with Process.isAlive() in Java 8
try {
Field field;
field = process.getClass().getDeclaredField("handle");
field.setAccessible(true);
long handle = (long) field.get(process);
field = process.getClass().getDeclaredField("STILL_ACTIVE");
field.setAccessible(true);
int stillActive = (int) field.get(process);
Method method;
method = process.getClass().getDeclaredMethod("getExitCodeProcess", long.class);
method.setAccessible(true);
int exitCode = (int) method.invoke(process, handle);
return exitCode == stillActive;
} catch (Exception e) {
// Reflection failed, use the backup solution
}
try {
process.exitValue();
return false;
} catch (IllegalThreadStateException e) {
return true;
}
}
public class ProcessEndNotifier extends Thread
{
Process process;
MyClass classThatNeedsToBeNotified;
public ProcessEndNotifier(MyClass classThatNeedsToBeNotified, Process process)
{
this.process = process;
this.classThatNeedsToBeNotified = classThatNeedsToBeNotified;
}
@Override
public void run()
{
try {
process.waitFor();
}
catch (InterruptedException e) {
classThatNeedsToBeNotified.processEnded();
}
classThatNeedsToBeNotified.processEnded();
}
}
现在你可以知道一个进程是否像这样运行:
public class MyClass
{
boolean isProcessRunning;
public static void main(String[]args)
{
Process process = Runtime.getRuntime().exec("foo -bar");
isProcessRunning = true;
new ProcessEndNotifier(this, process).run();
}
public void processEnded()
{
isProcessRunning = false;
// Or just do stuff here!
}
}
在 java 9 中,您可以使用isAlive()方法来检查进程是否仍在运行,如下所示:
Runtime rt = Runtime.getRuntime() ;
Process p = rt.exec(filebase+port+"/hlds.exe +ip "+ip+" +maxplayers "+players+ " -game cstrike -console +port "+port+" -nojoy -noipx -heapsize 250000 +map de_dust2 +servercfgfile server.cfg +lservercfgfile +mapcyclefile mapcycle.txt +motdfile motd.txt +logsdir logs -zone 2048",null, new File(filebase+port)) ;
boolean isRunning = p.toHandle.isAlive();
Java 5 及以后有一种方法可以使用java.util.concurrent.Future处理这个问题。
Future 表示异步计算的结果。 提供了检查计算是否完成、等待计算完成以及检索计算结果的方法。 结果只能在计算完成后使用 get 方法检索,必要时阻塞,直到它准备好。 取消由cancel 方法执行。 提供了其他方法来确定任务是正常完成还是被取消。 一旦计算完成,就不能取消计算。 如果为了可取消性而想使用 Future 但不提供可用结果,则可以声明 Future 形式的类型并返回 null 作为底层任务的结果。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.