web-dev-qa-db-fra.com

Comment trouver l'ID de processus (pid) d'un processus démarré en java?

Si j'obtiens un objet de processus dans Java via Runtime.getRuntime().exec(...) ou ProcessBuilder.start(), je peux l'attendre via Process.waitFor(), qui est comme Thread.join(), ou je pourrais le tuer avec Process.destroy(), qui est comme le Thread.stop() obsolète.

MAIS: Comment trouver le pid de l'objet de processus? Je ne vois pas de méthode pour le faire dans The Official Documentation . Puis-je faire cela en Java? Si c'est le cas, comment?

21
Leo Izen

Ce gars appelle bash pour obtenir le PID. Je ne sais pas s'il existe une solution Java au problème.

/**
 * 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 "";
  }
}

Source: http://www.coderanch.com/t/109334/Linux-UNIX/UNIX-process-ID-Java-program

10
nsfyn55

Semblable aux autres outils mentionnés, il existe l'outil de ligne de commande jps fourni avec le runtime Java. Il crache les PID de toutes les JVM en cours d'exécution. L'avantage est la sortie il faut analyser est limité aux seuls processus JVM.

7
Brent Worden

Leo, après avoir étudié ce problème pendant environ une semaine moi-même, je pense que l'approche de Jhurtado est probablement la "meilleure" approche que nous pouvons gérer en Java en ce moment. "Best" est entre guillemets car il a le effet secondaire très désagréable d'être essentiellement une "supposition" de ce qu'est votre enfant PID.

Si votre application Java génère rapidement des processus natifs dans un système à forte charge, il n'y a AUCUNE garantie que le PID que vous avez choisi dans votre calcul diff est le PID du processus démarré par le thread actuel ou que le PID du processus que vous choisissez a même été généré par notre application (peut-être que le système hôte exécutait déjà ce processus de toute façon).

Cela étant dit, si vous ne générez pas des dizaines de processus ou que le processus natif que vous générez est vraiment unique (une utilisation personnalisée que vous expédiez avec votre application), cette approche fonctionne très bien, auquel cas le PID du processus natif que vous recherchez est celui que vous voulez.

Sur Windows, vous pouvez utiliser 'tasklist' comme l'a souligné Jhurtado pour obtenir la liste complète des PID et filtrer celui que vous voulez (l'utilisation du commutateur de filtre/FI n'a pas fonctionné pour moi lors des tests).

Sur n'importe quel système * nix, vous pouvez utiliser "ps ax | grep" où NAME est un nom de processus comme 'nginx' ou 'httpd' que vous souhaitez filtrer pour obtenir votre liste.

De plus, si vous devez tuer des processus parasites (par exemple, sur VM) sur * nix, vous pouvez bien sûr utiliser "kill -9" et sur Windows, assez intéressant, vous pouvez utiliser 'taskkill'.

À peine optimal malheureusement.

0
Riyad Kalla

J'ai rencontré le même problème que vous. J'ai trouvé une solution assez décente, je recommande un léger sommeil avant de penser que le processus a officiellement démarré.

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

où findLastString est défini comme

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

Fondamentalement, cela obtiendra la liste des processus en cours d'exécution et trouvera le dernier exécuté avec, dans ce cas, le nom javaw.exe (Mon programme démarrait un processus Java Java) distinct. Vous pouvez remplacez javaw.exe par le nom du processus, que vous pouvez trouver à l'aide du Gestionnaire des tâches. Vous devrez également obtenir le pot Apache common IO jar).

0
Alex Coleman