2010-06-01 22 views

Trả lời

15

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.

+0

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

+0

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

+0

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

10

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); 
} 
+0

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ì ??? –

+0

@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. –

+0

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

0

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

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.

+1

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

Các vấn đề liên quan