كيف يمكنني العثور على معرف PID الخاص بي في Java أو JRuby على Linux؟
سؤال
أحتاج إلى العثور على PID لعملية التشغيل الحالية على نظام Linux (يمكن أن يكون حلاً يعتمد على النظام).لا تدعم Java الحصول على معرف العملية، ويوجد لدى JRuby حاليًا خطأ في طريقة Ruby، Process.pid.
هل هناك طريقة أخرى للحصول على PID؟
المحلول
اذا كنت تمتلك com.procfs بعد تثبيته، يمكنك العثور على معرف العملية عبر الرابط الرمزي /proc/self، الذي يشير إلى دليل اسمه هو معرف المنتج (توجد أيضًا ملفات هنا تحتوي على معلومات أخرى ذات صلة، بما في ذلك معرف المنتج، ولكن الدليل هو كل ما تحتاجه في هذا قضية).
وهكذا، مع جافا، يمكنك القيام بما يلي:
String pid = new File("/proc/self").getCanonicalFile().getName();
في JRuby، يمكنك استخدام نفس الحل:
pid = java.io.File.new("/proc/self").canonical_file.name
شكر خاص لقناة #stackoverflow على العقدة المجانية لمساعدتي في حل هذه المشكلة!(خاصة، يروب, جريج, ، و توبديك)
نصائح أخرى
تم اختباره فقط في Linux باستخدام Sun JVM.قد لا يعمل مع تطبيقات JMX الأخرى.
String pid = ManagementFactory.getRuntimeMXBean().getName().split("@")[0];
يمكنك استخدام واجهة JNI لاستدعاء وظيفة POSIX com.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
تتم كتابة معرف المنتج الأول بواسطة الصدفة والثاني بواسطة برنامج Java بعد عودة موجه الصدفة.∎
تفرخ عملية الصدفة التي ستقرأ معرف المنتج الأصلي لها.يجب أن يكون معرف الهوية الخاص بنا.هنا هو رمز التشغيل، دون استثناء ومعالجة الأخطاء.
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 $$`
قد يحل هذا محل السلسلة الأخيرة في المصفوفة المعطاة لـ exec
يتصل.
يمكنك تجربة getpid() في جي إن آر-بوسيكس.
كما أن لديها برنامج تضمين Windows POSIX الذي يستدعي getpid() من libc.لا حاجة إلى JNI.
Java 9
يقدم أخيرًا طريقة رسمية للقيام بذلك ProcessHandle:
ProcessHandle.current().pid();
هذا:
يحصل أولا على
ProcessHandle
مرجع للعملية الحاليةمن أجل الوصول إليها
pid
.
لا يوجد استيراد ضروري كما ProcessHandle
هو جزء من java.lang
.