Ich habe ein Programm, das fork()
und exec()
mehrere Prozesse in einer Kette haben kann.
Zum Beispiel: Prozess A - & gt; Gabel, Exec B - & gt; Gabel, Exec C - & gt; Gabel, Exec D. So A ist die Ur-Urgroßeltern von C.
Jetzt ist das Problem, dass ich keine Kontrolle über die Prozesse B, C und D habe. Es können also mehrere Dinge passieren.
setsid()
ausführen kann, um seine Prozessgruppe und Sitzung zu ändern. Daher kann ich mich nicht auf die Prozessgruppen-ID oder Eltern-ID verlassen, um alle Nachkommen von A zu verfolgen. Gibt es eine zuverlässige Möglichkeit, alle Nachkommen zu verfolgen? Genauer gesagt möchte ich alle Nachkommen töten (Waisen und andere).
Es wäre auch großartig, wenn es POSIX-konform ist.
Ich stimme caf setsid
Manchmal wird eine bestimmte "Super-Session" einen Prozessbaum enthalten. Es gibt kein Tool, das solche Super-Sessions in der POSIX-Toolbox bietet, aber ich werde ein paar Lösungen vorschlagen. Jede Lösung hat ihre eigenen Grenzen, daher ist es wahrscheinlich, dass sie nicht alle auf Ihren Fall anwendbar sind, aber hoffentlich wird eine davon geeignet sein.
Eine saubere Lösung besteht darin, die Prozesse in ihrer eigenen virtualisierten Umgebung auszuführen. Dies könnte ein FreeJSD-style sein, Linux Cgroups oder jede andere Art von Virtualisierungstechnologie. Die Einschränkungen dieses Ansatzes bestehen darin, dass Virtualisierungstechnologien vom Betriebssystem abhängig sind und die Prozesse in einem etwas anderen Kontext ablaufen.
Wenn Sie nur eine einzige Instanz dieser Prozesse auf dem System haben und Sie können root involvieren, führen Sie die Prozesse als dedizierter Benutzer aus. Die Super-Sitzung ist definiert als die Prozesse, die als dedizierter Benutzer ausgeführt werden. Töte die Nachkommen mit kill(-1, signum)
(beachte, dass dies den Killer-Prozess selbst auslöst, wenn er nicht blockiert oder das Signal behandelt wird).
Sie können den Prozess veranlassen, eine eindeutige Datei zu öffnen, indem Sie sicherstellen, dass das Flag FD_CLOEXEC
für den Dateideskriptor gesetzt ist. Alle untergeordneten Prozesse erben die geöffnete Datei dann, wenn sie das Flag FD_CLOEXEC
vor dem Aufruf von execve
explizit entfernen oder die Datei schließen. Töte die Prozesse mit fuser -k
oder indem du die Liste der Prozess-IDs mit fuser
oder lsof
erhältst ( fuser
ist in POSIX, aber nicht fuser -k
). Beachten Sie, dass es eine Race-Bedingung gibt: Ein Prozess kann zwischen die Zeit, die Sie fuser
aufrufen und die Zeit, die Sie es töten; Daher müssen Sie fuser
in einer Schleife aufrufen, bis keine Prozesse mehr auftreten (führen Sie keine Schleife durch, bis alle Prozesse tot sind, da dies eine Endlosschleife sein könnte, wenn einer der Prozesse Ihr Signal blockiert).
Sie können eine eindeutige zufällige Zeichenfolge generieren und eine Umgebungsvariable mit diesem Namen oder einem bekannten Namen und dieser eindeutigen Zeichenfolge als Wert definieren. Es wird von allen untergeordneten Prozessen übernommen, sofern sie nicht ihre Umgebung ändern. Es gibt keine Möglichkeit, nach Prozessen zu suchen, die auf ihrer Umgebung basieren oder sogar die Umgebung eines anderen Prozesses zu erhalten. Bei vielen Unix-Varianten können Sie die Informationen mit der Option ps
erhalten (z. B. ps -e
auf * BSD oder ps e
auf Linux); Die Information ist möglicherweise nicht leicht zu analysieren, aber das Vorhandensein der eindeutigen Zeichenkette ist ein ausreichender Indikator. Wie bei fuser
oben, notieren Sie die Notwendigkeit einer Schleife, um eine Race-Bedingung zu vermeiden, wenn ein Nachkomme fork
zu spät aufruft, um sein Kind zu bemerken, aber bevor Sie das Elter töten können.
Sie können LD_PRELOAD
eine kleine Bibliothek erstellen, die einen Thread abzweigt, der auf einem Kommunikationskanal horcht, und dessen Prozess bei der Benachrichtigung beendet. Dies kann den Prozess stören, wenn es von all seinen eigenen Threads weiß; Es ist nur eine Möglichkeit auf Architekturen, bei denen die Standardbibliothek immer Thread-sicher ist und Sie statisch verknüpfte Prozesse vermissen werden. Der Kommunikationskanal kann alles sein, was dem Master-Prozess ermöglicht, den Selbstmordbefehl zu senden; Eine Möglichkeit ist eine Pipe, bei der jeder absteigende Prozess eine blockierende Leseoperation ausführt und der Vorgängerprozess die Pipe schließt, um die Nachkommen zu benachrichtigen. Übergeben Sie die Datei-Deskriptor-Nummer über eine Umgebungsvariable.
Der POSIX-Weg dazu besteht einfach darin, Prozessgruppen zu verwenden. Abgeleitete Prozesse, die ihre Prozessgruppe / Sitzung explizit ändern, treffen eine bewusste Entscheidung, dass ihre Lebensdauer nicht von ihrem ursprünglichen Elternteil verfolgt wird - sie emanzipieren sich spezifisch von der Kontrolle der Eltern. Solche Prozesse sind keine Waisen - sie sind Erwachsene, die "das Nest geflogen" haben und die Kontrolle über ihr eigenes Leben ausüben wollen.
Tags und Links c process posix operating-system unix