2008-09-26 80 views
12

我需要在Linux平臺上找到當前正在運行的進程的PID(它可以是一個依賴於系統的解決方案)。 Java不支持獲取進程ID,JRuby目前在Ruby方法Process.pid中存在一個錯誤。如何在Linux上找到Java或JRuby中的PID?

是否有另一種獲得PID的方法?

+1

Process.pid不再打破,至少爲23年7月1日的jruby的 – 2016-02-29 18:01:30

回答

25

如果你安裝了procfs,你可以通過/ proc/self符號鏈接找到進程id,它指向一個名爲pid的目錄(這裏也有文件和其他相關信息,包括PID,但是在這種情況下,該目錄就是你所需要的)。

因此,與Java,你可以這樣做:

String pid = new File("/proc/self").getCanonicalFile().getName(); 

在JRuby中,你可以使用相同的解決方案:

pid = java.io.File.new("/proc/self").canonical_file.name 

特別感謝自由節點上的#stackoverflow通道對我的幫助解決這個! (具體而言,Jerub,greghTopdeck

7

僅在使用Sun JVM的Linux中進行了測試。可能不適用於其他JMX實現。

String pid = ManagementFactory.getRuntimeMXBean().getName().split("@")[0]; 
2

您可以使用JNI接口調用POSIX函數getpid()。這非常簡單。你從一個你需要的POSIX函數的類開始。我把它叫做POSIX.java

import java.util.*; 

class POSIX 
{ 
    static { System.loadLibrary ("POSIX"); } 
    native static int getpid(); 
} 

$ javac POSIX.java 

這之後您生成一個頭文件POSIX.h

$ javah -jni POSIX 

頭文件包含C原型與包裝功能編譯getpid函數。現在你必須實現這個功能,這很簡單。我做到了在POSIX.c

#include "POSIX.h" 

#include <sys/types.h> 
#include <unistd.h> 

JNIEXPORT jint JNICALL Java_POSIX_getpid (JNIEnv *env, jclass cls) 
{ 
    return getpid(); 
} 

現在你可以使用gcc編譯:

$ gcc -Wall -I/usr/lib/jvm/java-1.6.0-sun-1.6.0.21/include -I/usr/lib/jvm/java-1.6.0-sun-1.6.0.21/include/linux -o libPOSIX.so -shared -Wl,-soname,libPOSIX.so POSIX.c -static -lc 

你必須指定安裝的Java位置。就這樣。現在你可以使用它。創建一個簡單的GETPID程序:

public class getpid 
{ 
    public static void main (String argv[]) 
    { 
     System.out.println (POSIX.getpid()); 
    } 
} 

javac getpid.java編譯並運行它:

$ java getpid & 
[1] 21983 
$ 21983 

第一PID由shell寫,二是由Java編寫的程序返回shell提示符後。 ∎

2

產生一個shell進程,它將讀取其父進程的pid。那一定是我們的pid。這裏是正在運行的代碼,沒有例外和錯誤處理。

import java.io.*; 
import java.util.Scanner; 

public class Pid2 
{ 
    public static void main(String sArgs[]) 
    throws java.io.IOException, InterruptedException 
    { 
    Process p = Runtime.getRuntime().exec(
     new String[] { "sh", "-c", "ps h -o ppid $$" }); 
    p.waitFor(); 
    Scanner sc = new Scanner(p.getInputStream()); 
    System.out.println("My pid: " + sc.nextInt()); 
    Thread.sleep(5000); 
    } 
} 

該解決方案似乎是最好的,如果PID是要獲得只發出另一個shell命令。這足以包裝在反引號的命令將其作爲參數傳遞給另一個命令,例如:

nice `ps h -o ppid $$` 

這可能substitue給exec呼叫數組中的最後一個字符串。

0

您可以嘗試GETPID()在JNR-Posix

它也有一個Windows POSIX包裝調用GETPID()關閉的libc。不需要JNI。