检查进程是否在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开始,您可以:

process.isAlive()

对于Java 8之前的代码,我使用带有回退的reflection来捕获IllegalThreadStateException 。 reflection只适用于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; } } 

Java 5和on有一种方法可以使用java.util.concurrent.Future来处理它。

Future表示异步计算的结果。 提供方法以检查计算是否完成,等待其完成,以及检索计算结果。 结果只能在计算完成时使用方法get检索,必要时阻塞直到准备就绪。 取消由取消方法执行。 提供了其他方法来确定任务是否正常完成或被取消。 计算完成后,无法取消计算。 如果您希望为了取消可用性而使用Future而不提供可用的结果,则可以声明Future类型的类型,并作为基础任务的结果返回null。

 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();