2011-01-08 12 views
1
#include<stdlib.h> 
#include<unistd.h> 
#include<signal.h> 

int main(){ 

    pid_t pid = fork(); 

    if(pid==0){ 
      system("watch ls"); 
    } 
    else{ 
      sleep(5); 
      killpg(getpid(),SIGTERM); //to kill the complete process tree. 
    } 
    return 0; 
} 

Terminal:Wie kann ein Prozess sich selbst töten?

[email protected]:~/Desktop/testing$ gcc test.c 
[email protected]:~/Desktop/testing$ ./a.out 
Terminated 

für die ersten 5 Sekunden der Ausgabe der „Uhr ls“ gezeigt wird, und dann endet es, weil ich ein SIGTERM senden.

Frage: Wie kann ein Prozess sich selbst töten? Ich habe getötet (getpid(), SIGTERM);

Meine Hypothese: so während des Aufrufs kill() wechselt der Prozess zum Kernel-Modus. Der Kill-Aufruf sendet den SIGTERM an den Prozess und kopiert ihn in die Prozesstabelle des Prozesses. wenn der Prozess zurück in den Benutzermodus kommt, sieht er das Signal in seiner Tabelle und es beendet sich selbst (WIE? Ich weiß es wirklich nicht) (Ich glaube, ich gehe falsch (vielleicht ein Fehler) irgendwo in meiner Hypothese ... Also bitte erleuchten mich)

Dieser Code ist eigentlich ein Stub, den ich verwende, um meine anderen Module des Projekts zu testen. Es macht die Arbeit für mich und ich bin glücklich damit, aber es ist eine Frage in meinem Kopf, wie ein Prozess sich selbst tötet. Ich möchte die Schritt-für-Schritt-Hypothese kennen.

Vielen Dank im Voraus

Anirudh Tomer

+4

Warum sollte ein Prozess sich selbst töten wollen? Wenn es sich entscheidet zu beenden, wird es nicht einfach 'exit()' aufrufen? – 341008

+0

Wie tötet man das, was kein Leben hat ??? –

+0

Der Grund ist im obigen Fall, wenn Sie exit() aufrufen, anstatt zu töten, dann wird nur der Elternprozess gelöscht. Der untergeordnete Prozess wird verwaist, und init wird zu seinem neuen übergeordneten Element und wird weiterhin ausgeführt. – Durin

Antwort

0

Ich denke, es ist, wenn es das Signal SIGTERM in seinen Prozesstabellen sieht es seine Kindprozesse zuerst tötet (kompletten Baum, seit ich killpg() aufgerufen habe) und dann ruft exit() auf.

Ich bin immer noch auf der Suche nach einer besseren Antwort auf diese Frage.

2

Ihr Prozess stirbt, weil Sie killpg() verwenden, das ein Signal an eine Prozessgruppe und nicht an einen Prozess sendet.

Wenn Sie fork(), erben die Kinder vom Vater, unter anderem die Prozessgruppe. Von man fork:

* The child's parent process ID is the same as the parent's process ID. 

So töten Sie die Eltern zusammen mit dem Kind.

Wenn Sie eine einfache kill(getpid(), SIGTERM) tun, dann wird der Vater das Kind töten (das ist watch ing ls) und wird dann friedlich beenden.

+0

Nein, das ist nicht korrekt. Ersetzen Sie in meinem obigen Code "killpg" durch "kill" und Sie sehen nach 5 Sekunden, dass der Elternteil stirbt und das Kind vom Init-Prozess geerbt wird. Tue ps -a zu dieser Zeit. Eine andere Sache, die ich falsch mache, ist 'killpg (getpid(), SIGTERM);' aber da pgid und pid des Elternprozesses gleich sind, funktioniert es hier. Auch der Kindprozess hat den gleichen pgid. Es sollte 'killpg (getpgid (getpid()), SIGTERM);' sein, wenn BASH einen untergeordneten Prozess abgibt und es einen 'pgid'-Befehl ausführt und ihn so an seinen' pid' anpasst, so dass das auch für das Kind funktioniert killpg bash bleibt sicher. – Durin

1

Während des Aufrufs von kill() wechselt der Prozess in den Kernelmodus. Der Kill-Aufruf sendet den SIGTERM an den Prozess und kopiert ihn in die Prozesstabelle des Prozesses. wenn der Prozess in den Benutzermodus zurückkommt sieht er das Signal in seiner Tabelle und es beendet sich (WIE? Ich weiß es wirklich nicht)

In Linux, wenn aus dem Kernel-Modus in den User-Space-Modus Rückkehr der Der Kernel prüft, ob noch ausstehende Signale zugestellt werden können. Wenn es einige gibt, liefert es die Signale kurz bevor es in den Benutzerraummodus zurückkehrt. Es kann auch zu anderen Zeiten Signale senden, z. B. wenn ein Prozess unter select() blockiert und dann beendet wurde oder wenn ein Thread auf einen nicht zugeordneten Speicherort zugreift.

-3

Das ist super-einfach in Perl:

{ 
     local $SIG{TERM} = "IGNORE"; 
     kill TERM => -$$; 
    } 

Umwandlung in C ist für den Leser als Übung.

+0

woher kam Perl dazwischen ?? Trotzdem danke für den Informationsaustausch. Ich weiß nicht, Perl, so kann es sein, wenn ich anfangen, damit zu arbeiten, werde ich dieses Ding sehen, – Durin

0
kill(getpid(), SIGKILL); // itself I think 

Getestet habe ich es nach einem fork mit Fall 0: und es verließ regelmäßig von separatem Elternprozess.

Ich weiß nicht, ob dies ein Standardzertifizierungsverfahren ist ....

(ich von meinem psensor-Tool, das der CPU-Auslastung Rückkehr in 34% wie ein normales Programmcode mit ein Zähler gestoppt sehen) .