Trong Linux khi tôi chạy hàm hủy trên đối tượng java.lang.Process (Đó là đúng kiểu gõ java.lang.UNIXProcess) nó sẽ gửi một SIGTERM tín hiệu để xử lý, là có một cách để giết nó với SIGKILL?làm thế nào tôi có thể giết một quá trình Linux trong java với SIGKILL Process.destroy() hiện SIGTERM
Trả lời
Không sử dụng Java thuần túy.
Cách thay thế đơn giản nhất của bạn là sử dụng Runtime.exec()
để chạy lệnh kill -9 <pid>
dưới dạng quy trình bên ngoài.
Thật không may, nó không phải là đơn giản để có được giữ của PID. Bạn sẽ cần sử dụng ma thuật đen phản chiếu để truy cập trường private int pid
hoặc gây rối xung quanh đầu ra từ lệnh ps
.
CẬP NHẬT - thực sự, có một cách khác. Tạo một tiện ích nhỏ (chương trình C, kịch bản lệnh shell, bất kỳ thứ gì) sẽ chạy ứng dụng bên ngoài thực. Mã tiện ích để nó nhớ PID của tiến trình con, và thiết lập một trình xử lý tín hiệu cho SIGTERM sẽ SIGKILL tiến trình con.
Stephen câu trả lời của anh ấy là chính xác. Tôi đã viết những gì ông nói:
public static int getUnixPID(Process process) throws Exception
{
System.out.println(process.getClass().getName());
if (process.getClass().getName().equals("java.lang.UNIXProcess"))
{
Class cl = process.getClass();
Field field = cl.getDeclaredField("pid");
field.setAccessible(true);
Object pidObject = field.get(process);
return (Integer) pidObject;
} else
{
throw new IllegalArgumentException("Needs to be a UNIXProcess");
}
}
public static int killUnixProcess(Process process) throws Exception
{
int pid = getUnixPID(process);
return Runtime.getRuntime().exec("kill " + pid).waitFor();
}
Bạn cũng có thể nhận được pid theo cách này:
public static int getPID() {
String tmp = java.lang.management.ManagementFactory.getRuntimeMXBean().getName();
tmp = tmp.split("@")[0];
return Integer.valueOf(tmp);
}
trên Linux, tôi chạy lệnh thông qua java (quá trình tương tác): nslookup -> google, điều này treo quá trình, và tôi không thể giết quá trình này. Vì vậy, bây giờ tôi đã sử dụng đề xuất của bạn, nhưng nó không chấm dứt quá trình này, nó chỉ bị treo và tôi không thể chấm dứt chương trình của tôi. Tôi thậm chí đã cố gắng để giết pid bằng tay nhưng không có avail, những gì tôi nên làm gì ??? –
@Space Rocker: một kill đơn giản gửi một SIGTERM. "Kill -9" gửi SIGKILL. Hãy thử "kill -9 -1": gửi SIGKILL cho tất cả các tiến trình trong nhóm tiến trình mà pid> 1. Nếu nó không giết nó thì sẽ không có gì xảy ra. Nhưng điều này sẽ làm việc. –
Chắc chắn sử dụng cách thứ hai để có được tự PID. VisualVM cũng làm như vậy. Cách trước đây là hack xấu xí, nó không phải là nền tảng chéo, và có thể không hoạt động trong các phiên bản Java trong tương lai. – Espinosa
Nếu bạn biết tên quá trình bạn có thể sử dụng pkill
Runtime.getRuntime().exec("pkill firefox").waitFor();
Kể từ Java 1.8
bạn có thể gọi phương thức destroyForcibly()
, gọi số destroy()
đã gặp hod theo mặc định, nhưng theo các tài liệu Java, tất cả các quy trình con được trả về bởi ProcessBuilder
hoặc Runtime.exec()
triển khai phương pháp này.
Thật không may hiện nay việc thực hiện chỉ đơn giản gọi là 'destroy()'. Xem tại đây: https://bugs.openjdk.java.net/browse/JDK-8056139 – Joe
Tôi có thể làm điều đó như thế này hoặc trong JNI, mặc dù tôi không háo hức làm theo cách này, làm cách nào bạn biết được pid của quá trình bạn muốn giết? – ekeren
Lời cảm ơn đầu tiên cho những câu trả lời này. phản ánh và JNI/exec là khu nghỉ mát cuối cùng của tôi, tôi tự hỏi nếu ai đó có thể tìm thấy một cách thanh lịch hơn để làm điều này. – ekeren
Tôi cũng khó khăn về một trình bao bọc, thực sự ông chủ của tôi khó khăn về nó :), Vì vậy, tôi hiểu rằng không có cách thẳng về phía trước để làm điều này mà bạn biết. – ekeren