Проверьте, запущен ли процесс в Windows / Linux - PullRequest
9 голосов
/ 27 апреля 2011

у меня есть процесс

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 немного отличается, так как она включает в себя несколько вхождений и должна проверять только определенный процесс

Ответы [ 7 ]

23 голосов
/ 28 марта 2013
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()

2 голосов
/ 14 марта 2016

Начиная с Java 8 вы можете сделать:

process.isAlive ()

2 голосов
/ 27 апреля 2011

Вы можете сделать p.waitFor(), чтобы поток, выполнивший инструкцию, дождался завершения процесса.Затем вы можете выполнить логику очистки / перезапуска сразу после того, как этот код будет выполнен, когда процесс умрет.Однако я не уверен, как это будет работать, если процесс зависнет, а не умрет, но это может стоить попробовать.Кстати, я бы порекомендовал использовать Java Service Wrapper и supervisord в вашем случае, если это то, что вы собираетесь делать на производстве.

1 голос
/ 12 августа 2017

Для кода, предшествующего 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 голосов
/ 21 сентября 2017

В 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();
0 голосов
/ 24 мая 2014
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!
    }
}
0 голосов
/ 27 апреля 2011

В Java 5 и более поздних версиях есть способ справиться с этим, используя java.util.concurrent.Future .

Future представляет результат асинхронного вычисления. Предоставляются методы для проверки того, завершено ли вычисление, для ожидания его завершения и для извлечения результата вычисления. Результат может быть получен только с помощью метода get, когда вычисление завершено, при необходимости блокируется, пока не будет готово. Отмена производится методом отмены. Предоставляются дополнительные методы, чтобы определить, была ли задача выполнена нормально или была отменена. Как только вычисление завершено, вычисление не может быть отменено. Если вы хотите использовать Future ради отменяемости, но не предоставить пригодный для использования результат, вы можете объявить типы формы Future и вернуть null в результате выполнения основной задачи.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...