"Weggeforkte" Kinder auch beenden wenn der "Elternprozess" beendet wird?

02/02/2016 - 19:49 von Manuel Reimer | Report spam
Hallo,

ich bin nun schon einige Zeit am Probieren, bekomme es aber noch nicht
hin...

Ich schreibe ein Programm, welches im ersten Prozess auf ein bestimmtes
Device wartet (blockierend). Sobald ein solches Device gesteckt wird,
wird eine weitere Instanz weggeforkt (der eigentliche Usermode-Treiber).
Der "Elternprozess" làuft dabei stàndig weiter um weitere Devices zu
erkennen.

Soweit so gut...

Wie aber bekomme ich alles, was der Elternprozess so weggeforkt hat,
wieder beendet sobald der Elternprozess ein SIGTERM bekommt.

Ich habe gelesen, dass sowas mit Prozessgruppen gehen soll.

Und eben eine solche sollte man mit "setsid" anlegen können, was aber
nur geht wenn man auch den Hauptprozess in den Hintergrund forkt.

Deshalb habe ich gedacht ich könnte mehrere Fliegen mit einer Klappe
schlagen und nutze jetzt:

http://man7.org/linux/man-pages/man3/daemon.3.html

Schien mir passend, weil das Programm eh als Daemon laufen soll.

Hilft aber nicht. Wenn der Elternprozess beendet wird, dann laufen die
Kindprozesse munter weiter...

Danke für jeden Tipp.

Gruß

Manuel
 

Lesen sie die antworten

#1 Rainer Weikusat
02/02/2016 - 20:31 | Warnen spam
Manuel Reimer writes:

[...]

Wie aber bekomme ich alles, was der Elternprozess so weggeforkt hat,
wieder beendet sobald der Elternprozess ein SIGTERM bekommt.

Ich habe gelesen, dass sowas mit Prozessgruppen gehen soll.

Und eben eine solche sollte man mit "setsid" anlegen können, was aber
nur geht wenn man auch den Hauptprozess in den Hintergrund forkt.



Das ist nicht ganz richtig: setsid erzeugt eine neue 'session' (Menge
von Prozessgruppen) wenn der ausfuehrende Prozess nicht bereits ein
Prozessgruppenleiter ('process group leader') ist, dh zu einer
Prozessgruppe gehoert, deren Prozessgruppennummer (process group id)
gleicher seiner Prozessnummer ('process id' aka 'pid') ist. Das kann man
sicherstellen, in dem man setsid aus einem geforkten Prozess heraus
aufruft denn der ist garantiert nicht der erste Prozess in seiner
Prozessgruppe. Mit setpgid(2) koenne Prozessgruppen flexibler gehandhabt
werden.

Signale werden allerdings nicht per default an alle Mitglieder einer
Prozessgruppe geschickt sondern an einen Prozess. Um sie an eine Gruppe
zu schicken, muss man eine negative pgid als erstes Argument von kill(2)
benutzen. Man kann einen signal handler benutzen um SIGTERM
'weiterzuverteilen'.

Beispiel:

-
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

static void kill_em_all(int unused)
{
(void)unused;

/*
SIGTERM an alle
*/
kill(-getpid(), SIGTERM);
}

int main(void)
{
int rc;

/*
wir wollen unsere eigene Prozessgruppe
*/
rc = setpgid(0, 0);
if (rc == -1) {
perror("setpgid");
exit(1);
}

/*
^C sendet SIGINT an alle Mitglieder der
Vordergrundprozessgruppe. Um zu verhindern, dass es die
Kindprozesse terminiert, starte sie mit 'SIGINT ignorieren'.
*/
signal(SIGINT, SIG_IGN);

/*
"Seid fruchtbar und mehrt euch"
*/
if (fork() == 0) pause();
if (fork() == 0) pause();
if (fork() == 0) pause();

/*
Installiere relay-handler und warte auf SIGINT.
*/
signal(SIGINT, kill_em_all);
pause();

return 0;
}

Ähnliche fragen