9
votes

Vérifiez si le processus fonctionne sous Windows / Linux

J'ai un processus

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


0 commentaires

7 Réponses :


3
votes

Vous pouvez faire un p.waitfor () donc le fil qui exécutait l'instruction attend jusqu'à ce que le processus soit terminé. Vous pouvez ensuite effectuer la logique de nettoyage / redémarrage juste après, car ce code sera exécuté lorsque le processus meurt. Cependant, je ne suis pas sûr de savoir comment cela fonctionnerait si le processus se bloque au lieu de mourir, mais cela pourrait valoir la peine d'essayer. Au fait, je vous recommanderais d'utiliser wrapper de service Java et Supervisord dans votre cas si c'est quelque chose que vous allez faire sur la production.


1 commentaires

Dans ce cas, je devrais créer un nouveau fil à chaque fois que je commence un nouveau processus? et continuez à interroguer sur le même fil?



0
votes

Java 5 et sur un moyen de gérer cela en utilisant java.util.concurrent.future .

Un avenir représente le résultat d'un calcul asynchrone. Des méthodes sont fournies pour vérifier si le calcul est terminé, pour attendre son achèvement et récupérer le résultat du calcul. Le résultat ne peut être récupéré que à l'aide de la méthode d'obtenir une fois le calcul terminé, bloquant si nécessaire jusqu'à ce qu'il soit prêt. L'annulation est effectuée par la méthode d'annulation. Des méthodes supplémentaires sont fournies pour déterminer si la tâche remplie normalement ou a été annulée. Une fois qu'un calcul est terminé, le calcul ne peut pas être annulé. Si vous souhaitez utiliser un avenir pour l'incident d'annulation mais que vous ne fournissez pas de résultat utilisable, vous pouvez déclarer des types de formulaires futurs et renvoyer NULL à la suite de la tâche sous-jacente.


3 commentaires

Ne comprenez pas la méthode ... une explication claire s'il vous plaît :)


À Java 5, un nouveau paquet puissant varié a été ajouté, Java.Util.ConCurrent. Il rend la gestion beaucoup plus facile des sous-processus en fournissant des cours qui savent travailler avec des cas d'utilisation différents de manière efficace et de manière excessive. Si vous devez mettre en place un producteur / consommateur ou une file d'attente de blocage, ou une tâche planifiée, la plupart des travaux difficiles sont effectués pour vous. La future classe est utilisée pour suivre l'état d'un thread et même obtenir une valeur de retour quand elle existe. Il semble que l'utilisation de ce paquet et de l'avenir en particulier vous ferait économiser beaucoup de travail.


Quelle est la connexion entre processus et futur ?



24
votes
boolean isRunning(Process process) {
    try {
        process.exitValue();
        return false;
    } catch (Exception e) {
        return true;
    }
}
See http://docs.oracle.com/javase/6/docs/api/java/lang/Process.html#exitValue()

1 commentaires

Je sais que le flux de contrôle ne devrait pas utiliser des exceptions, mais Java ne nous a pas donné une meilleure alternative.



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

0 commentaires


1
votes

Pour le code Pre Java 8, j'utilise la réflexion avec une baisse pour attraper illégalHreadStateException code>. La réflexion ne fonctionnera que sur les instances de processimpl code>, mais comme c'est ce qui est retourné par processbuilder code> C'est généralement le cas pour moi.

    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 commentaires

0
votes

en Java 9, vous pouvez utiliser Isalive () Méthode Pour vérifier si un processus est Stil fonctionner comme ceci:

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


0 commentaires