2011-04-27 40 views
9

我有一个过程检查/ 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有点不同,因为它涉及多个事件,并且只能检查某个特定进程

回答

2

您可以执行p.waitFor(),以便执行该语句的线程等待,直到该进程完成。然后您可以立即执行清理/重新启动逻辑,因为该代码将在进程死亡时执行。然而,我不确定如果这个过程挂起而不是死亡将如何工作,但这可能值得一试。顺便说一句,如果这是你要在生产中做的事,我会建议在你的情况下使用Java Service Wrappersupervisord

+0

?并保持同一个线程的轮询? – Varun 2011-04-29 05:59:00

0

Java 5和有办法处理这个使用java.util.concurrent.Future

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

+1

dint了解方法...请清楚说明:) – Varun 2011-04-27 11:21:36

+0

在Java 5中,增加了一个新的功能强大的包java.util.concurrent。通过提供知道如何高效并以线程安全方式处理不同用例的类,它使得管理子进程变得更加容易。如果您需要实施生产者/消费者,阻塞队列或计划任务,则大部分艰苦工作都将为您完成。Future类用于跟踪线程的状态,甚至在它存在时从它获取返回值。看起来,使用这个软件包,特别是Future,会为你节省很多工作。 – 2011-04-30 01:49:23

+1

'Process'和'Future'之间的连接是什么? – 2013-03-28 10:59:53

0
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! 
    } 
} 
1

从Java 8中,你可以这样做:

process.isAlive()

+1

虽然这可能会在理论上回答这个问题,[这将是更可取的](/ meta.stackoverflow.com/q/8259)在这里包括答案的重要部分,并提供参考链接。 – 2016-03-14 20:31:53

0

对于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; 
    } 
} 
0

在java中9,您可以使用isAlive()的方法来检查,如果一个进程STIL运行这样的:

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(); 
在这种情况下,我应该创建一个新的线程,每次我开始一个新的进程