2011-03-12 34 views
21

如果我通過Runtime.getRuntime().exec(...),或ProcessBuilder.start()獲得的Java進程對象,我可以通過Process.waitFor()等待吧,這就好比Thread.join(),我也可以用Process.destroy()殺了它,這就像過時的Thread.stop()如何找到在java中啓動的進程的進程ID(pid)?

但是:我如何找到處理對象的PID?我在The Official Documentation中沒有看到這樣做的方法。我可以在Java中執行此操作嗎?如果是這樣,怎麼樣?

回答

10

這傢伙叫一聲打壞得到PID。我不確定是否有解決問題的Java解決方案。

/** 
* 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 ""; 
    } 
} 

來源: http://www.coderanch.com/t/109334/Linux-UNIX/UNIX-process-ID-java-program

+0

我認爲這會給出JVM進程的PID ......而不是Java產生的進程,我相信這是問題的要求。 – splashout

+0

我認爲你需要仔細閱讀。它產生了一個進程,只有工作是將它自己的PID回顯到它本身被連接到與JVM關聯的stdin文件描述符的stdout。 – nsfyn55

+0

向量是舊式的,並且是同步的 - 沒有真正需要使用該類型的集合 - 請嘗試使用ArrayList。只是說。 – user924272

-2

我認爲在Java中你最好的拍攝是之前和產卵你的孩子的過程後得到的tasklist。進行差異化並獲得您的PID。

您可以通過發出Runtime.getRuntime.exec("tasklist");
注意tasklist.exe不包含在Windows XP家庭版獲得任務列表,但你仍然可以下載它。

+0

你假設我在Windows上,我不是。 –

7

所提到的其他工具一樣,存在jps命令行工具自帶的Java運行時。它吐出所有運行的JVM的PID。好處是需要解析的輸出僅限於JVM進程。

+0

另一個好處是:它是跨平臺的,不像tasklist。 –

0

獅子座,尋找到這個問題,大約一個星期後,我自己覺得我Jhurtado的做法很可能是「最好」的方法,我們現在就可以在Java的管理。 「最好」是用引號引起的,因爲它有一個非常討厭的副作用,基本上是對你的孩子PID的「猜測」。

如果您的Java應用程序在高負載系統中快速生成本機進程,則不能保證您在差異計算中獲取的PID是由當前線程啓動的進程的PID,你選擇的進程甚至是由我們的應用產生的(也許主機系統已經在運行那個進程了)。這就是說,如果你沒有產生數十個進程或你產生的本地進程是真正獨特的(你的應用程序附帶的一些自定義實用程序),那麼這種方法工作正常,在這種情況下本地進程的PID你正在尋找的是你想要的。

在Windows中可以使用「任務列表」作爲Jhurtado指出,獲得的PID的完整列表和篩選你想要的(使用/ FI過濾器開關,我在測試中沒有工作)。

在任何* nix系統上,您可以使用「ps ax | grep」,其中NAME是您想過濾以獲取列表的某個進程名稱,如'nginx'或'httpd'。

此外,如果您需要在* nix中,你可以在Windows上使用的過程「殺-9」,並殺死流浪過程(例如,在VM退出),有趣的是,你可以使用「TASKKILL 」。

幾乎最佳不幸。

0

我遇到同樣的問題,因爲你。我發現了一個相當不錯的解決方案,我建議在確保該過程正式啓動之前稍微休息一下。

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

其中findLastString被定義爲

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; 
} 

基本上這將讓正在運行的進程的列表,並找到最近跑了一個用,在這種情況下,名稱的javaw.exe(我的程序開始一個單獨的java進程)。您可以將javaw.exe替換爲進程的名稱,您可以使用任務管理器找到它。您也需要獲得Apache常見的IO jar。

相關問題