Prozess.exitValue() und Process.destroy () - Funktionen
Ich habe experimentiert mit Process
und ProcessBuilder
und kommen mit dieser SSCCE.
import java.io.IOException;
public class TestProcess {
public static void main(String[] args) {
Process process = null;
ProcessBuilder pb = new ProcessBuilder("notepad.exe");
try {
process = pb.start();
} catch (IOException e) {e.printStackTrace();}
//have some time to close notepad
try {
Thread.sleep(10*1000);
} catch (InterruptedException ignored) {}
try {
System.out.println(process.exitValue());
} catch (IllegalThreadStateException e) {
System.out.println(e);
}
if (process != null)
process.destroy();
/*try {
Thread.sleep(0, 1);
} catch (InterruptedException ignored) {}*/
System.out.println(process.exitValue());
}
}
- Wenn ich diesen code ausführen, und schließen Sie Editor, bevor 10s timeout.
destroy()
nennen zeigt nicht jedes problem auf Anhieb zu stoppen, ist bereits beendet, Prozess. Warum? - Wenn führen Sie diesen code und schließen Sie nicht den Editor überhaupt (mit kommentierten zweiten Schlaf)
Scheint es, dass zu zerstören, wird der asynchrone Aufruf (nur ein signal zu senden?) die Ergebnisse in Ausnahme im zweiten exitValue()
java.lang.IllegalThreadStateException: process has not exited
Exception in thread "main" java.lang.IllegalThreadStateException: process has not exited
at java.lang.ProcessImpl.exitValue(ProcessImpl.java:246)
at TestProcess.main(TestProcess.java:30)
- Wenn ich diesen code ausführen und schließen Sie nicht den Editor überhaupt (mit unkommentierte zweiten Schlaf) und dann den zweiten
exitValue
schmeißt Ausnahme, auch wenn der Schlaf Wert ist nur 1ms. Ist es, weil dersleep()
Aufwand selbst?
ZweiteexitValue
zurückkehren würde 1.
PS. Ich führen Sie es von Windows 7 und Eclipse.
- 1)
} catch (IOException ignored) {}
Ziehen, Ihre Fehler aus dem sand und stattdessen} catch (IOException e) { e.printStackTrace(); }
2) stellen Sie Sicher, dass der code implementiert die Empfehlungen von "Wenn Laufzeit.exec() won 'T" 3) um genau Zu sein, ein SSCCE erfordert Importe. - 1) ich bin sicher, Sie können immer ausführen notepad bei Windows, 2) Was Sie tun bedeuten? 3) ja, nur ein import.
- danke, ich habe den code aktualisieren, für 1) und 3).
Du musst angemeldet sein, um einen Kommentar abzugeben.
Warum würde es zeigen, ein problem? Sie versuchen zu zerstören, ein Prozess, der schon zerstört war. Die Spezifikation
Process.destroy()
nicht sagen, was passiert, wenn es nichts zu zerstören, so ist es logisch (nehme ich an) davon ausgehen, dass, wenn es nichts zu zerstören, dann gibt es nichts zu meckern. Vergleichen Sie mitThread.join()
, die nicht nur sterben, wenn der thread bereits beendet ist.Der einzige Weg, um zu töten ein Prozess ist, es zu senden ein signal. Auf einigen OS ist, gibt es andere, mehr "gewaltsame" Weise (auf einigen Plattformen, zum Beispiel, ist es möglich, entfernen Sie einfach den Prozess aus der OS-Liste der Laufenden Prozesse. Die Ergebnisse sind undefiniert, und es endet meist hässlich), aber zumindest mit den Plattformen, die ich kenne, es ist wirklich alles über das senden von Signalen.
Möglich, in der Tat, dass es ist, weil es braucht Zeit, um zu berufen
Thread.sleep()
. Erhöhen Sie den timeout-Wert.sleep()
aufgerufen zweitenexitValue()
1 zurück und keine Ausnahme auslösen.ProcessImpl
auf Windows;exitValue()
fordert eine native Funktion, die ich glauben endet Aufruf von WindowsGetExitCodeProcess
. Nichts in der Dokumentation von entweder Methoden erwähnen, was über einen beliebigen exit-code1
für einen Prozess, der noch nicht wirklich beendet. Bizarr in der Tat.1
zurückgegeben, anderenfalls wird eine Ausnahme ausgegeben. Also meine Vermutung ist, dasssleep
braucht viel mehr Zeit, genug für den Prozess zu beenden.1
ist eine dokumentierte "formale" exit-code fürNotepad
.exitValue
Drucke0
notepad.exe
anmutig, seine exit-code sein soll (und ist)0
. Die Frage ist - gibt es irgendeine Dokumentation über die Umstände, in denennotepad.exe
gibt einen exit-code1
? und wenn ja, was sind diese Umstände?Ich gehe davon aus, dass die destroy () - Methode ruft die native windows-Funktion TerminateProcess.
Blick auf MSDN, fand ich dies:
So, ich denke, es erklären zu zerstören ist in der Tat asynchron.
Weiteren Auszug aus der gleichen Quelle:
Ich denke, dass "unconditionnally" kann erklären, warum der Aufruf von destroy() auf einen Prozess beenden nicht scheitern.
Hoffe, dass dies helfen. (wirklich eine interessante Frage !)
ProcessImpl.java
aufdestroy
Aufruf der Methode native FunktionterminateProcess
:terminateProcess
ist Plattform-abhängig und für Windows finden Sie Quellen hier. Es ist nur call Windows TerminateProcess-Funktion (link zu dieser Funktion war bisher die Antwort, oder Sie können google es) mituExitCode=1
- das ist, warum exit-code zerstört Prozess ist1
.In linux aussieht, ist verwendet etwas ähnliches, um diese. Und als Beweis nächste code zurück
143
in ubuntu, die dem entsprechenSIGTERM
(https://stackoverflow.com/a/4192488/3181901):