Как найти идентификатор процесса (pid) процесса, запущенного в java?

Если я получаю объект процесса в Java через Runtime.getRuntime().exec(...) или ProcessBuilder.start(), я могу дождаться его через Process.waitFor(), что похоже на Thread.join(), или я могу убить его с помощью Process.destroy(), что похоже на устаревшее Thread.stop().

НО: как мне найти pid объекта процесса? Я не вижу способа сделать это в официальном Документация. Могу ли я сделать это на Java? Если да, то как?


person Leo Izen    schedule 12.03.2011    source источник


Ответы (5)


Этот парень звонит в Баш, чтобы получить PID. Я не уверен, есть ли решение проблемы на Java.

/**
 * Gets a string representing the pid of this program - Java VM
 */
public static String getPid() throws IOException,InterruptedException {

  Vector<String> commands=new Vector<String>();
  commands.add("/bin/bash");
  commands.add("-c");
  commands.add("echo $PPID");
  ProcessBuilder pb=new ProcessBuilder(commands);

  Process pr=pb.start();
  pr.waitFor();
  if (pr.exitValue()==0) {
    BufferedReader outReader=new BufferedReader(new InputStreamReader(pr.getInputStream()));
    return outReader.readLine().trim();
  } else {
    System.out.println("Error while getting PID");
    return "";
  }
}

Источник: http://www.coderanch.com/t/109334/Linux-UNIX/UNIX-process-ID-java-program

person nsfyn55    schedule 12.03.2011
comment
Я думаю, что это даст pid процесса JVM... а не процесса, порожденного Java, который, как я полагаю, является тем, что задает вопрос. - person splashout; 02.08.2016
comment
Я думаю, вам нужно читать немного внимательнее. Он порождает процесс, единственной задачей которого является повторение собственного PID на его стандартный вывод, который сам передает дескриптор файла стандартного ввода, связанный с JVM. - person nsfyn55; 03.08.2016
comment
Векторы устарели и синхронизированы — нет реальной необходимости использовать этот тип коллекции — попробуйте вместо этого использовать ArrayList. Просто говорю. - person user924272; 01.06.2017
comment
Просто сказать что? Это не относится к проблеме. Вопрос о доступе к лучшим практикам PID, а не java. - person nsfyn55; 02.06.2017

Подобно другим упомянутым инструментам, есть инструмент командной строки jps, который поставляется со средой выполнения Java. Он выдает PID всех запущенных JVM. Преимущество заключается в том, что вывод, который необходимо проанализировать, ограничивается только процессами JVM.

person Brent Worden    schedule 12.03.2011
comment
Еще одно преимущество: он кроссплатформенный, в отличие от списка задач. - person Mike Baranczak; 12.03.2011

Лео, изучая эту проблему около недели, я думаю, что подход Джуртадо, вероятно, является «лучшим» подходом, который мы можем использовать в Java прямо сейчас. «лучший» в кавычках, потому что у него есть очень неприятный побочный эффект, заключающийся в том, что он в основном «угадывает», какой у вашего ребенка PID.

Если ваше Java-приложение быстро порождает собственные процессы в системе с высокой нагрузкой, НЕТ НИКАКОЙ гарантии, что PID, который вы получаете при вычислении различий, является PID процесса, запущенного текущим потоком, или что PID выбранного вами процесса был даже порожденным нашим приложением (возможно, хост-система уже запускала этот процесс).

При этом, если вы не создаете десятки процессов или собственный процесс, который вы создаете, действительно уникален (некоторые пользовательские утилиты, которые вы поставляете с вашим приложением), тогда этот подход отлично работает, и в этом случае PID собственного процесса, который вы ищете это тот, который вы хотите.

В Windows вы можете использовать «tasklist», как указал Джуртадо, чтобы получить полный список PID и отфильтровать тот, который вам нужен (использование переключателя фильтра /FI не сработало для меня при тестировании).

В любой системе *nix вы можете использовать «ps ax | grep», где NAME — это имя процесса, например «nginx» или «httpd», которое вы хотите отфильтровать, чтобы получить список.

Кроме того, если вам нужно убить блуждающие процессы (например, при выходе из виртуальной машины) в *nix, вы, конечно, можете использовать «kill -9», а в Windows, что интересно, вы можете использовать «тасккилл'.

Вряд ли оптимально, к сожалению.

person Riyad Kalla    schedule 16.08.2011

Я столкнулся с той же проблемой, что и вы. Я нашел довольно приличное решение, я рекомендую немного поспать, прежде чем он подумает, чтобы убедиться, что процесс официально запущен.

Process p = Runtime.getRuntime().exec("cmd /c tasklist");
StringWriter writer = new StringWriter();
IOUtils.copy(p.getInputStream(), writer);
String theString = writer.toString();
//System.out.println(theString);
id = findLastString("javaw.exe                     .{1,} Console                    1", theString);
System.out.println(id);

где findLastString определяется как

public static String findLastString(String pattern, String in) {
     Pattern p = Pattern.compile(pattern);
     Matcher matcher = p.matcher(in);
     String it= "";
     while(matcher.find()) {
       it = matcher.group();
       try {
        Thread.sleep(10);
       } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
       }
     }
     int firstIndex=pattern.indexOf(".{1,}");
     int lastIndex=it.substring(firstIndex).indexOf(pattern.substring(pattern.indexOf(".{1,}")+5))+firstIndex;
     String dotOn = it.substring(pattern.indexOf(".{1,}"));

     it=it.substring(firstIndex, lastIndex);
     return it;
 }

По сути, это получит список запущенных процессов и найдет последний запущенный, в данном случае с именем javaw.exe (моя программа запускала отдельный процесс java). Вы можете заменить javaw.exe именем процесса, которое вы можете найти с помощью диспетчера задач. Вам также понадобится общая банка ввода-вывода Apache.

person Alex Coleman    schedule 28.05.2012

Я думаю, что в Java лучше всего получить список задач до и после создания вашего дочернего процесса. Сделайте diff и получите свой PID.

вы можете получить список задач, отправив Runtime.getRuntime.exec("tasklist");
Обратите внимание, что файл tasklist.exe не включен в выпуск Windows XP Home, но вы все равно можете его загрузить.

person jhurtado    schedule 12.03.2011
comment
Вы предполагаете, что я работаю в Windows, а это не так. - person Leo Izen; 13.03.2011