Wie erhalte ich die PID des Prozesses, den ich gerade im Java-Programm gestartet habe?

Lesezeit: 7 Minuten

Wie erhalte ich die PID des Prozesses den ich gerade
Raf

Ich habe einen Prozess mit folgendem Code gestartet

 ProcessBuilder pb = new ProcessBuilder("cmd", "/c", "path");
 try {
     Process p = pb.start();       
 } 
 catch (IOException ex) {}

Jetzt muss ich die PID des Prozesses kennen, den ich gerade gestartet habe.

  • Dies kann einigen helfen: stackoverflow.com/questions/35842/process-id-in-java

    – Grammin

    20. Januar 11 um 17:33 Uhr

  • Keine Ahnung, wie man es in Java macht, aber falls es Ihr Skript ist, können Sie es ändern, damit es seine PID ausgibt und es von p.getInputStream() analysiert.

    – maaartinus

    20. Januar 11 um 17:37 Uhr

  • KEIN “exaktes Duplikat” desjenigen, der für das Schließen gestimmt hat. Diese Frage hat damit zu tun, die PID des Java-Prozesses selbst zu finden, nicht einen neuen Prozess, den der Java-Prozess hervorgebracht hat.

    – Markus Peters

    20. Januar 11 um 17:37 Uhr

  • Dies gibt die PID der zurück Laufen Host-VM lautete die ursprüngliche Frage, wie die PID des untergeordneten Prozesses lauten würde, der von der laufenden Java-App gestartet wird. Diese Frage adressiert es: stackoverflow.com/questions/5284139/…

    – Riad Kalla

    16. August 11 um 1:42 Uhr

  • Es ist möglich, dass Java 9 eine Standard-API dafür bereitstellt: openjdk.java.net/jeps/102

    – Raedwald

    13. Mai ’15 um 9:31 Uhr

1643906227 1 Wie erhalte ich die PID des Prozesses den ich gerade
tscherny

Seit Java 9 Klasse Process hat eine neue Methode long pid()also ist es so einfach wie

ProcessBuilder pb = new ProcessBuilder("cmd", "/c", "path");
try {
    Process p = pb.start();
    long pid = p.pid();      
} catch (IOException ex) {
    // ...
}

Wie erhalte ich die PID des Prozesses den ich gerade
Amir Afghani

Dafür gibt es noch keine öffentliche API. siehe Sonne Fehler 4244896Sonne Fehler 4250622

Als Problemumgehung:

Runtime.exec(...)

gibt ein Objekt vom Typ zurück

java.lang.Process

Die Process-Klasse ist abstrakt, und was Sie zurückerhalten, ist eine Unterklasse von Process, die für Ihr Betriebssystem entwickelt wurde. Zum Beispiel auf Macs kehrt es zurück java.lang.UnixProcess die ein privates Feld namens hat pid. Mit Reflection können Sie den Wert dieses Felds leicht abrufen. Dies ist zugegebenermaßen ein Hack, aber es könnte helfen. Was braucht man den PID denn überhaupt?

  • Unter Windows gibt es java.lang.ProcessImpl zurück, das keine Vorstellung von PID hat. Ihre Lösung ist leider nicht plattformübergreifend.

    – Espinosa

    28. Juni 13 um 20:55 Uhr

  • Es gibt ein weiteres recht gutes Beispiel, das eine angemessene plattformübergreifende Unterstützung bietet unter:github.com/flapdoodle-oss/de.flapdoodle.embed.process/blob/…

    – satyagraha

    09.12.14 um 08:46 Uhr

  • Ich weiß nichts über das OP, aber ich muss in der Lage sein, den Prozess irgendwann zu beenden und möglicherweise neu zu starten.

    – Nate Lockwood

    20. Juli 16 um 23:20 Uhr

  • Beachten Sie, dass der Hack unter Java 9 unter Linux nicht mehr funktioniert – bei Mac bin ich mir nicht sicher.

    – Oliver Gondža

    7. April 17 um 12:04 Uhr

  • Für Java 9+ Benutzer finden hier eine reine JDK-Lösung: stackoverflow.com/a/42104000/363573

    – Stefan

    3. Juli 17 um 9:12 Uhr


Diese Seite hat das HOWTO:

http://www.golesny.de/p/code/javagetpid

Unter Windows:

Runtime.exec(..)

Gibt eine Instanz von „java.lang.Win32Process“) ODER „java.lang.ProcessImpl“ zurück

Beide haben ein privates Feld “Handle”.

Dies ist ein Betriebssystem-Handle für den Prozess. Sie müssen diese + Win32-API verwenden, um PID abzufragen. Auf dieser Seite finden Sie Einzelheiten dazu.

  • Siehe Antwort von arcsin, wie man es mit JNA macht.

    – Panayotis

    8. August 17 um 9:53 Uhr

  • Siehe Antworten von LRBH10 und czerny. Das sind bessere Ansätze im Jahr 2019.

    – Shamit Verma

    14. Mai 19 um 14:55 Uhr

Wie erhalte ich die PID des Prozesses den ich gerade
LRBH10

Im Unix-System (Linux & Mac)

 public static synchronized long getPidOfProcess(Process p) {
    long pid = -1;

    try {
      if (p.getClass().getName().equals("java.lang.UNIXProcess")) {
        Field f = p.getClass().getDeclaredField("pid");
        f.setAccessible(true);
        pid = f.getLong(p);
        f.setAccessible(false);
      }
    } catch (Exception e) {
      pid = -1;
    }
    return pid;
  }

1643906228 732 Wie erhalte ich die PID des Prozesses den ich gerade
arcsin

Enthalten jna (sowohl “JNA” als auch “JNA Platform”) in Ihrer Bibliothek und verwenden Sie diese Funktion:

import com.sun.jna.Pointer;
import com.sun.jna.platform.win32.Kernel32;
import com.sun.jna.platform.win32.WinNT;
import java.lang.reflect.Field;

public static long getProcessID(Process p)
    {
        long result = -1;
        try
        {
            //for windows
            if (p.getClass().getName().equals("java.lang.Win32Process") ||
                   p.getClass().getName().equals("java.lang.ProcessImpl")) 
            {
                Field f = p.getClass().getDeclaredField("handle");
                f.setAccessible(true);              
                long handl = f.getLong(p);
                Kernel32 kernel = Kernel32.INSTANCE;
                WinNT.HANDLE hand = new WinNT.HANDLE();
                hand.setPointer(Pointer.createConstant(handl));
                result = kernel.GetProcessId(hand);
                f.setAccessible(false);
            }
            //for unix based operating systems
            else if (p.getClass().getName().equals("java.lang.UNIXProcess")) 
            {
                Field f = p.getClass().getDeclaredField("pid");
                f.setAccessible(true);
                result = f.getLong(p);
                f.setAccessible(false);
            }
        }
        catch(Exception ex)
        {
            result = -1;
        }
        return result;
    }

Sie können JNA auch von herunterladen Hier und JNA-Plattform von Hier.

  • Könnten Sie bitte erklären, was der obige Code tut? Auf diese Weise werden alle zukünftigen Besucher verstehen. Danke

    – Zeichnete Szurko

    15. April 17 um 15:10 Uhr

  • Die Antwort von Shamit Verma stellt fest, warum es so gemacht werden muss. Windows gibt Ihnen keine PID, sondern ein Handle, also müssen Sie das Handle in PID umwandeln.

    – Panayotis

    8. August 17 um 9:54 Uhr

1643906228 590 Wie erhalte ich die PID des Prozesses den ich gerade
Glenneroo

Ich glaube, ich habe eine Lösung gefunden, die ziemlich kugelsicher aussieht, während sie auf den meisten Plattformen funktioniert. Hier ist die Idee:

  1. Erstellen Sie einen JVM-weiten Mutex, den Sie erwerben, bevor Sie einen neuen Prozess erzeugen/einen Prozess beenden
  2. Verwenden Sie plattformabhängigen Code, um die Liste der untergeordneten Prozesse + PIDs Ihres JVM-Prozesses abzurufen
  3. Spawnen Sie einen neuen Prozess
  4. Erwerben Sie eine neue Liste von untergeordneten Prozessen + PIDs und vergleichen Sie sie mit der vorherigen Liste. Der Neue ist dein Typ.

Da Sie nur nach untergeordneten Prozessen suchen, kann Ihnen kein anderer Prozess auf derselben Maschine Unrecht tun. JVM-weiter Mutex gibt Ihnen dann die Gewissheit, dass der neue Prozess der richtige ist.

Das Lesen der untergeordneten Prozessliste ist einfacher als das Abrufen der PID von Prozessobjekten, da es keine WIN-API-Aufrufe unter Windows erfordert und, was noch wichtiger ist, es wurde bereits in mehreren Bibliotheken durchgeführt.

Unten ist eine Implementierung der obigen Idee mit JavaSysMon Bücherei. Es

class UDKSpawner {

    private int uccPid;
    private Logger uccLog;

    /**
     * Mutex that forces only one child process to be spawned at a time. 
     * 
     */
    private static final Object spawnProcessMutex = new Object();

    /**
     * Spawns a new UDK process and sets {@link #uccPid} to it's PID. To work correctly,
     * the code relies on the fact that no other method in this JVM runs UDK processes and
     * that no method kills a process unless it acquires lock on spawnProcessMutex.
     * @param procBuilder
     * @return 
     */
    private Process spawnUDK(ProcessBuilder procBuilder) throws IOException {
        synchronized (spawnProcessMutex){            
            JavaSysMon monitor = new JavaSysMon();
            DirectUDKChildProcessVisitor beforeVisitor = new DirectUDKChildProcessVisitor();
            monitor.visitProcessTree(monitor.currentPid(), beforeVisitor);
            Set<Integer> alreadySpawnedProcesses = beforeVisitor.getUdkPids();

            Process proc = procBuilder.start();

            DirectUDKChildProcessVisitor afterVisitor = new DirectUDKChildProcessVisitor();
            monitor.visitProcessTree(monitor.currentPid(), afterVisitor);
            Set<Integer> newProcesses = afterVisitor.getUdkPids();

            newProcesses.removeAll(alreadySpawnedProcesses);

            if(newProcesses.isEmpty()){
                uccLog.severe("There is no new UKD PID.");
            }
            else if(newProcesses.size() > 1){
                uccLog.severe("Multiple new candidate UDK PIDs");
            } else {
                uccPid = newProcesses.iterator().next();
            }
            return proc;
        }
    }    

    private void killUDKByPID(){
        if(uccPid < 0){
            uccLog.severe("Cannot kill UCC by PID. PID not set.");
            return;
        }
        synchronized(spawnProcessMutex){
            JavaSysMon monitor = new JavaSysMon();
            monitor.killProcessTree(uccPid, false);
        }
    }

    private static class DirectUDKChildProcessVisitor implements ProcessVisitor {
        Set<Integer> udkPids = new HashSet<Integer>();

        @Override
        public boolean visit(OsProcess op, int i) {
            if(op.processInfo().getName().equals("UDK.exe")){
                udkPids.add(op.processInfo().getPid());
            }
            return false;
        }

        public Set<Integer> getUdkPids() {
            return udkPids;
        }
    }
}

  • Könnten Sie bitte erklären, was der obige Code tut? Auf diese Weise werden alle zukünftigen Besucher verstehen. Danke

    – Zeichnete Szurko

    15. April 17 um 15:10 Uhr

  • Die Antwort von Shamit Verma stellt fest, warum es so gemacht werden muss. Windows gibt Ihnen keine PID, sondern ein Handle, also müssen Sie das Handle in PID umwandeln.

    – Panayotis

    8. August 17 um 9:54 Uhr

In meinen Tests hatten alle IMPL-Klassen das Feld “PID”. Das hat bei mir funktioniert:

public static int getPid(Process process) {
    try {
        Class<?> cProcessImpl = process.getClass();
        Field fPid = cProcessImpl.getDeclaredField("pid");
        if (!fPid.isAccessible()) {
            fPid.setAccessible(true);
        }
        return fPid.getInt(process);
    } catch (Exception e) {
        return -1;
    }
}

Stellen Sie nur sicher, dass der zurückgegebene Wert nicht -1 ist. Wenn dies der Fall ist, analysieren Sie die Ausgabe von ps.

  • Es gilt nicht java.lang.ProcessImpl. Bei mir schlägt es zum Beispiel unter Windows fehl.

    – Oliver Gondža

    8. Februar 16 um 9:50 Uhr

.

757580cookie-checkWie erhalte ich die PID des Prozesses, den ich gerade im Java-Programm gestartet habe?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy