Je voudrais savoir comment "tuer" un processus qui a démarré. Je suis au courant de l'API Process, mais je ne suis pas sûr. Si je peux l'utiliser pour "tuer" un processus déjà en cours d'exécution, tel que firefox.exe, etc. Si l'API Process peut être utilisée, pouvez-vous m'indiquer le direction correcte? Si non, quelles sont les autres options disponibles? Merci.
Si vous démarrez le processus depuis dans votre application Java (par exemple, en appelant Runtime.exec()
ou ProcessBuilder.start()
), vous disposez d'une référence Process
valide et vous pouvez appeler la méthode destroy()
dans la classe Process
pour tuer ce processus particulier.
Sachez toutefois que si le processus que vous appelez crée de nouveaux sous-processus, ceux-ci ne peuvent pas être terminés (voir http://bugs.Sun.com/bugdatabase/view_bug.do?bug_id=4770092 ).
D'autre part, si vous souhaitez supprimer des processus externes (que vous n'avez pas créés depuis votre application Java), vous pouvez alors appeler des utilitaires O/S qui vous permettent de le faire. Par exemple, vous pouvez essayer une commande Runtime.exec()
sur kill
sous Unix/Linux et vérifier les valeurs renvoyées pour vous assurer que l'application a été supprimée ou non (0 signifie succès, -1 signifie erreur). Mais cela va bien sûr rendre votre plate-forme applicative dépendante.
Sous Windows, vous pouvez utiliser cette commande
taskkill /F /IM <processname>.exe
pour le tuer avec force. Alors il sera
Runtime.getRuntime().exec("taskkill /F /IM <processname>.exe")
AFAIU Java.lang.Process est le processus créé par Java lui-même (comme Runtime.exec ('firefox'))
Vous pouvez utiliser des commandes dépendant du système telles que
Runtime rt = Runtime.getRuntime();
if (System.getProperty("os.name").toLowerCase().indexOf("windows") > -1)
rt.exec("taskkill " +....);
else
rt.exec("kill -9 " +....);
Je suis tombé par hasard sur un autre moyen de tuer par force Unix (pour ceux qui utilisent Weblogic). C’est moins cher et plus élégant que de lancer/bin/kill -9 via Runtime.exec () .
import weblogic.nodemanager.util.Platform;
import weblogic.nodemanager.util.ProcessControl;
...
ProcessControl pctl = Platform.getProcessControl();
pctl.killProcess(pid);
Et si vous avez du mal à obtenir le pid, vous pouvez utiliser la réflexion sur Java.lang.UNIXProcess , par exemple:
Process proc = Runtime.getRuntime().exec(cmdarray, envp);
if (proc instanceof UNIXProcess) {
Field f = proc.getClass().getDeclaredField("pid");
f.setAccessible(true);
int pid = f.get(proc);
}
Il s’agit peut-être d’un défaut d’interpréteur Java, mais Java sur HPUX ne fait pas kill -9, mais seulement kill -TERM.
J'ai fait un petit test testDestroy.Java:
ProcessBuilder pb = new ProcessBuilder(args);
Process process = pb.start();
Thread.sleep(1000);
process.destroy();
process.waitFor();
Et l'invocation:
$ tusc -f -p -s signal,kill -e /opt/Java1.5/bin/Java testDestroy sh -c 'trap "echo TERM" TERM; sleep 10'
meurt après 10 ans (pas tué après 1 comme prévu) et montre:
...
[19999] Received signal 15, SIGTERM, in waitpid(), [caught], no siginfo
[19998] kill(19999, SIGTERM) ............................................................................. = 0
...
Faire la même chose sur Windows semble tuer le processus, même si le signal est traité (mais cela peut être dû au fait que Windows n'utilise pas de signaux pour détruire).
En fait, j'ai trouvé Java - Le code source de Process.destroy () pour Linux la mise en oeuvre de threads et d'openjava semble également utiliser -TERM, ce qui semble très faux.
Essayez le:
String command = "killall <your_proccess>";
Process p = Runtime.getRuntime().exec(command);
p.destroy();
si le processus est toujours en cours, ajoutez:
p.destroyForcibly();
Avec Java 9
, nous pouvons utiliser ProcessHandle qui facilite l'identification et le contrôle des processus natifs:
ProcessHandle
.allProcesses()
.filter(p -> p.info().commandLine().map(c -> c.contains("firefox")).orElse(false))
.findFirst()
.ifPresent(ProcessHandle::destroy)
où "firefox" est le processus à tuer.
Ce:
Tout d’abord répertorie tous les processus en cours d’exécution sur le système en tant que Stream<ProcessHandle>
Lazily filtre ce flux pour ne conserver que les processus dont la ligne de commande lancée contient "firefox". commandLine
ou command
peuvent être utilisés en fonction de la façon dont nous voulons récupérer le processus.
Trouve le premier processus filtré répondant à la condition de filtrage.
Et si au moins une ligne de commande du processus contenait "firefox", la tue avec destroy
.
Aucune importation nécessaire car ProcessHandle
fait partie de Java.lang
.
Vous pouvez tuer un processus Windows (SIGTERM) démarré à partir de Java en appelant la méthode destroy sur l'objet Process. Vous pouvez également tuer tous les processus enfants (depuis Java 9).
Le code suivant démarre un fichier de commandes, attend dix secondes, puis supprime tous les sous-processus et finalement le processus de traitement par lots lui-même.
ProcessBuilder pb = new ProcessBuilder("cmd /c my_script.bat"));
Process p = pb.start();
p.waitFor(10, TimeUnit.SECONDS);
p.descendants().forEach(ph -> {
ph.destroy();
});
p.destroy();