2011-03-12 52 views
21

Nếu tôi nhận được một đối tượng quá trình trong Java thông qua Runtime.getRuntime().exec(...), hoặc ProcessBuilder.start(), tôi có thể chờ cho nó qua Process.waitFor(), mà là giống như Thread.join(), hoặc tôi có thể giết nó với Process.destroy(), mà cũng giống như phản Thread.stop().Làm cách nào để tìm ID quá trình (pid) của quá trình được bắt đầu bằng java?

NHƯNG: Làm thế nào để tìm thấy pid của đối tượng quy trình? Tôi không thấy phương pháp để làm điều đó trong The Official Documentation. Tôi có thể làm điều này trong Java không? Nếu vậy, làm thế nào?

Trả lời

10

Anh chàng này gọi ra để bash lấy PID. Tôi không chắc chắn nếu có một giải pháp java cho vấn đề.

/** 
* Gets a string representing the pid of this program - Java VM 
*/ 
public static String getPid() throws IOException,InterruptedException { 

    Vector<String> commands=new Vector<String>(); 
    commands.add("/bin/bash"); 
    commands.add("-c"); 
    commands.add("echo $PPID"); 
    ProcessBuilder pb=new ProcessBuilder(commands); 

    Process pr=pb.start(); 
    pr.waitFor(); 
    if (pr.exitValue()==0) { 
    BufferedReader outReader=new BufferedReader(new InputStreamReader(pr.getInputStream())); 
    return outReader.readLine().trim(); 
    } else { 
    System.out.println("Error while getting PID"); 
    return ""; 
    } 
} 

Nguồn: http://www.coderanch.com/t/109334/Linux-UNIX/UNIX-process-ID-java-program

+0

Tôi nghĩ rằng điều này sẽ cung cấp cho pid của quá trình JVM ... không phải là quá trình sinh ra bởi Java mà tôi tin là câu hỏi được đặt ra. – splashout

+0

Tôi nghĩ bạn cần đọc kỹ hơn một chút. Nó sinh ra một quá trình mà chỉ có công việc là để lặp lại PID của riêng nó đến stdout của nó mà chính nó là đường ống đến bộ mô tả tệp stdin liên kết với JVM. – nsfyn55

+0

Vectơ là kiểu cũ và được đồng bộ hóa - không cần sử dụng loại bộ sưu tập đó - hãy thử sử dụng ArrayList thay thế. Chỉ cần nói. – user924272

-2

Tôi nghĩ rằng trong Java bắn tốt nhất của bạn là để có được những tasklist trước và sau khi đẻ trứng quá trình con quý vị. Tạo sự khác biệt và lấy PID của bạn.

bạn có thể tải Danh sách nhiệm vụ bằng cách phát hành Runtime.getRuntime.exec("tasklist");
Lưu ý rằng tasklist.exe không được bao gồm trong ấn bản Windows XP Home, nhưng bạn vẫn có thể tải xuống.

+0

Bạn đang giả sử tôi đang ở trên Windows, mà tôi không phải. –

7

Tương tự như các công cụ khác được đề cập, có công cụ dòng lệnh jps đi kèm với thời gian chạy Java. Nó phun ra các PID của tất cả các JVM đang chạy. Lợi ích là đầu ra cần phân tích cú pháp chỉ giới hạn trong các quy trình JVM.

+0

Một lợi ích khác: đó là đa nền tảng, không giống như tasklist. –

0

Leo, sau khi xem xét vấn đề này trong khoảng một tuần, tôi nghĩ rằng cách tiếp cận của Jhurtado có lẽ là cách tiếp cận "tốt nhất" mà chúng tôi có thể quản lý trong Java ngay bây giờ. "tốt nhất" là trong dấu ngoặc kép bởi vì nó có tác dụng phụ rất khó chịu về cơ bản là một "đoán" ở những gì con PID của bạn.

Nếu ứng dụng Java của bạn đang sinh ra quy trình gốc nhanh chóng trong hệ thống tải cao, KHÔNG bảo đảm rằng PID bạn lấy trong tính toán khác là PID của Quy trình do Chủ đề hiện tại hoặc PID của quá trình bạn chọn thậm chí được sinh ra bởi ứng dụng của chúng tôi (có thể hệ thống máy chủ đang chạy quá trình đó). Điều đó đang được nói, nếu bạn không sinh sản hàng chục quá trình hoặc quá trình sinh sản bạn đang sinh sản thực sự độc đáo (một số tùy chỉnh bạn gửi với ứng dụng của bạn) thì phương pháp này hoạt động tốt trong trường hợp PID của quá trình bản địa bạn đang tìm kiếm là cái bạn muốn.

Trên cửa sổ, bạn có thể sử dụng 'tasklist' vì Jhurtado đã chỉ ra để có danh sách đầy đủ các PID và bộ lọc cho bộ lọc bạn muốn (sử dụng bộ lọc/FI không hoạt động).

Trên mọi hệ thống * nix, bạn có thể sử dụng "ps ax | grep" trong đó NAME là một số tên quá trình như 'nginx' hoặc 'httpd' mà bạn muốn lọc để lấy danh sách của mình.

Ngoài ra, nếu bạn cần phải giết quá trình đi lạc (ví dụ, trên lối ra VM) trên * nix nhiên bạn có thể sử dụng "kill -9" và trên Windows, thú vị đủ, bạn có thể sử dụng 'taskkill '.

Rất tiếc, tối ưu không may.

0

Tôi gặp sự cố tương tự như bạn.Tôi tìm thấy một giải pháp khá tốt, tôi đề nghị một giấc ngủ nhẹ trước khi nó nghĩ để đảm bảo quá trình đã chính thức bắt đầu lên.

Process p = Runtime.getRuntime().exec("cmd /c tasklist"); 
StringWriter writer = new StringWriter(); 
IOUtils.copy(p.getInputStream(), writer); 
String theString = writer.toString(); 
//System.out.println(theString); 
id = findLastString("javaw.exe      .{1,} Console     1", theString); 
System.out.println(id); 

nơi findLastString được định nghĩa là

public static String findLastString(String pattern, String in) { 
    Pattern p = Pattern.compile(pattern); 
    Matcher matcher = p.matcher(in); 
    String it= ""; 
    while(matcher.find()) { 
     it = matcher.group(); 
     try { 
     Thread.sleep(10); 
     } catch (InterruptedException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
     } 
    } 
    int firstIndex=pattern.indexOf(".{1,}"); 
    int lastIndex=it.substring(firstIndex).indexOf(pattern.substring(pattern.indexOf(".{1,}")+5))+firstIndex; 
    String dotOn = it.substring(pattern.indexOf(".{1,}")); 

    it=it.substring(firstIndex, lastIndex); 
    return it; 
} 

Về cơ bản này sẽ nhận được danh sách các tiến trình đang chạy, và tìm ra gần đây nhất là chạy một với, trong trường hợp này, tên javaw.exe (Chương trình của tôi đã bắt đầu một quá trình java riêng biệt). Bạn có thể thay thế javaw.exe bằng tên của quá trình mà bạn có thể tìm thấy bằng cách sử dụng Trình quản lý Tác vụ. Bạn cũng sẽ cần lấy bình IO thông thường của Apache.

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