2008-12-17 8 views
5

Ich habe einen Prozessnamen und ich muss ein kill() Signal an diesen Prozess senden, aber ich brauche seine PID, um kill() aufzurufen. Ich möchte nur verwenden:Find PID eines Prozesses nach Name ohne Verwendung von popen() oder system()

popen("pidof process_name"); 

als letzte Sache. Gibt es eine andere Möglichkeit, den PID Prozess herauszufinden? Eine Möglichkeit, an die ich denken könnte, ist, eine Socket-Anfrage an diesen Prozess zu senden und nach seiner PID zu fragen.

Der andere Weg ist ein wenig zu kompliziert für einen einfachen Code Ich schreibe: zu tun, was pidof command's source code tatsächlich tut (es verwendet einen Funktionsaufruf find_pid_by_name(), aber das macht eine Menge Dinge).

Wenn keine einfache Lösung möglich ist, habe ich dies zu tun:

system("pkill <process_name>"); 

und überprüfen Sie die Return-Code. Aber wird es auf allen Linux-Rechnern sicher verfügbar sein?

Antwort

4

Sie erwähnten, dass Sie Linux verwenden. Es ist nicht die sauberste Lösung, aber Sie können jeden Eintrag in/proc durchlaufen und den Prozessnamen in cmdline nach dem suchen, was Sie suchen.

+0

sollte ziemlich einfach mit boost :: regex und boost :: filesystem ich denke, –

+0

ich einmal sah in die strace-Ausgabe von pidof, und dachte, es tut es auf die gleiche Weise. (kann sich aber zwischendurch geändert haben) –

+2

procfs liest sind sehr günstig. Für diesen speziellen Zweck müssten Sie nicht wirklich anfangen zu lesen, bis Sie PID 1000 erreichen, dann müssen Sie 40 - 60 untersuchen. Denken Sie nicht an das Lesen eines konventionellen FS, es ist viel billiger. –

4

Verwendung sysctl - Example code

EDIT - es ist in Linux verfügbar see here

+0

Vielen Dank! Ich werde das untersuchen. – Srikanth

+1

Dies funktioniert nur auf * BSD, nicht Linux. – ephemient

0

Dies scheint gut für mich zu arbeiten.

Möglicherweise möchten Sie jedoch den vollständigen Pfad des Prozesses angeben, damit Sie einen Prozess mit einem ähnlichen Namen nicht beenden.

Der Hauptvorteil davon ist, dass Sie das Signal angeben können, das Sie senden möchten.

system("killall -s 9 process_name"); 
+0

Das ist nicht anders als die pkill Version ... –

0

warum nicht fcntl mit F_GETOWN verwenden?

+0

Das funktioniert nur, wenn fcntl auf einem Socket-Deskriptor aufgerufen wird, und es muss darauf geachtet werden, ob Sie eine PID oder eine Prozessgruppe erhalten (ein negatives Ergebnis von fcntl). Der Aufruf von fcntl für eine normale Datei mit F_GETOWN ist in POSIX nicht angegeben. http://www.opengroup.org/onlinepubs/009695399/functions/fcntl.html –

2

Procfs-Lesevorgänge sind sehr billig, viele Leute denken daran, durch/proc wie sie iterieren durch/zu durchlaufen, es ist wirklich nicht der Fall überhaupt.

Sparen Sie etwas Zeit, indem Sie einen Eintrag überspringen, der unter 1000 ist, es hat keinen Sinn, Kernel-Threads zu untersuchen. Also, im Grunde .. nach opendir(), wenn strtoint() denkt, der Eintrag ist ein int, und dass int größer als oder gleich 1000 ist, lesen Sie einfach/proc /% d/stat.

Versuchen Sie, den Drang zu vermeiden, nur die "exe" -Link aufzulösen, da dies nicht den Status des Prozesses, der das Signal erhalten wird, sagen wird. Wenn sich das Ziel zum Beispiel im Zustand "D" (Disk Sleep) befindet, möchten Sie wissen, dass das Signal nicht sofort oder vielleicht nie geliefert wird, wenn der D-Zustand mehrjährig ist.

Auf den meisten Systemen werden 70 - 120 Prozesse zu untersuchen sein und Sie werden oft Ihr Ziel finden, bevor Sie das Ende erreichen.

+0

@tinkertim: Danke für den Tipp, wusste nicht, lesen in/proc ist nicht wie das Lesen eines FS! – Srikanth

2

Sie erwähnen, "Eine Möglichkeit, an die ich denken könnte, ist, eine Socket-Anfrage an diesen Prozess zu senden und nach seiner PID zu fragen." Es klingt wie der Prozess, den Sie versuchen zu töten, ist ein Programm, das Sie geschrieben haben.

Wenn dies der Fall ist, ist die Kanonical Sache zu tun, die PID in einer Datei (in der Regel unter/var/run, wenn Sie darauf Zugriff haben) während des Programms zu speichern, und entfernen Sie die Datei, wenn das Programm beendet.Auf diese Weise erkennen, ob nicht das Programm läuft ist so einfach wie

if kill -0 $(cat /var/run/myprog.pid 2>/dev/null) 2>/dev/null; then 
    echo Running! 
else 
    rm -f /var/run/myprog.pid 
    echo "Not running." 
end 

Eine sorgfältige Untersuchung aller Auswirkungen des obigen Codes wird wahrscheinlich Sie viel über beibringen, wie PID-Dateien arbeiten. Oder Sie können nur nach einer ausführlicheren Erklärung fragen.