An Alle ein frohes und erfolgreiches neues Jahr, Joerg Rossdeutscher wrote:
Danke für deine Erklärungen. Ich bohren mal etwas nach:
PPS: War gut, habe selber wieder einiges Aufgefrischt, intensiviert.
Am Mi, den 31.12.2003 schrieb Gerald Goebel um 00:10:
Mit dem exit kannst du ja auch noch was zurückgeben, z. B. 0 für richtig ausgeführt, oder -1 für Fehler. An wen soll das denn gehen?
Ich kann doch normalerweise jeden Prozess (solange er nicht innerhalb von Kernel-Routinen hängt) abschiessen. Wieso soll das hier anders sein?
Es ist nicht anders, der Prozess wird ja auch abgesch0ssen, aber in der Prozessrabelle, bleibt er noch stehen, er lebt also in der Prozesstabelle noch weiter obwohl er tot ist, daher auch der Name: Zombie, lebender Toter. Jetzt ist natürlich die Frage: Welchen Rückgabewert hat er dann? Auch das ist eindeutig geregelt: Da der Kernel keinen Rückgabewert findet, setzt er dafür das Signal ein, mit dem der Prozess abgeschoßen wurde. Für C, gibt es dafür Makros um den Wert auszulesen, ist irgendwas mit AFAIK Bitverschiebung. Damit kannst du denn genau sagen warum der Prozess beendet wurde.
Also nochmal: Prozesse, die von einem Prozess erzeugt wurden, sich beendet haben und die nicht erwartet werden, werden zu Zombies, und stehen damit noch immer zur Abholung in der Prozess-Tabelle bereit.
Es spielt also keine Rolle, ob sauber beendet wurde oder nicht.
Kannst du "Abholung" definieren?
Mit "Abholung" meine ich hier, das der Rückgabewert (der immer vorhanden ist) für die pid aus der Prozesstabelle mit einem wait-Befehl (es gibt mehrere) abgerufen wird. Naormalerweise sollte das der Parentprozess machen, wenn er nicht mehr existiert, macht das Prozess-No. 1 (init). BTW: Sollte ich gesagt haben Prozess-No. 1 (init) hat keinen Parentprozess, so ist das falsch, beim erneuten Durchsichten meiner Skripte, fand ich, daß nur der Prozess mit der No. 0 kein Parentprozess hat. Prozess-No. 0 ist der boot-prozess. ps -C init --format "%p %P %c" PID PPID COMMAND 1 0 init
Und noch eine Verständnisfrage:
1. Ich dissoziiere den Prozess ja (setsid). Das sollte eigentlich (technisch) die Abhängigkeit zwischen den Prozessen beenden. Ich habe das noch nicht getestet, aber theoretisch sollte Child sogar weiterlaufen, wenn Parent beendet wird.
Was verstehst du unter "dissoziiere", bitte Definition. Ich glaube, du verwechselst hier 2 Sachen: Mit setsid, eröffnest du eine neue Session, und machst den aktuellen Prozess zum Sessionleader dieser Session. Man muß aber folgende 3 Sachen getrennt betrachten: 1. Prozesse 2. Prozessgruppen 3. Sessions Also fangen wir mal bei 3 an, was ist eine Session? Wenn du dich einloggst, eröffnest du damit einen neue Session, mit der shell als Session-Leader. Wenn du dich ausloggst, schließt du diese Session. Wie du siehst kann eine Session Prozessgruppen und Prozesse enthalten. Was geschieht also bei einer Session, Interessant ist das Schließen der Session, denn sonst verhält sie sich wie ein normaler Prozess, dh. du kannst mit ihr alles machen was du mit einem normalen Prozess auch machen kannst, der einzige unterschied ist, das sie noch zusätzlich die Funktion des Session-Leaders inne hat. Also was macht der Session-Leader wenn er beendet wird? Er schickt an alle Prozesse, die in der Session sind ein Signal, das sie sich zu beenden haben, das ist das Signal, das er selber auch bekommen hat. Dann scheckt er ob sich seine Prozesse beendet haben, wenn nicht, nimmt er das nächst härtere Signal, bis zum kill. Über dieses Phänomen haben wir uns alle mit Sicherheit schon mal geärgert, einen lang laufenden Prozess in den Hintergrund geschickt, und dann ausgeloggt, um beim nächsten einloggen festzustellen, daß, der Hintergrundprozess nicht bis zum Enden gearbeitet hat. Um genau das zu machen, dafür gibt es den Befehl "nohup", er macht folgendes: er forkt sich, macht den neuen Prozess zu einem neuen Session-Leader, und überlagert dann den Prozess mit dem Code des Programms, das man angegeben hat. Es ist damit von der alten Session unabhängig, wird also nicht beendet, wenn diese beendet wird. Einen Session ohne Session-Leader gibt es nicht, wird der Session-Leader beendet, verschwindet auch die Session und damit alls ihre Prozesse. Was ist eine Prozessgruppe? Jeder Prozess gehört auch zu einer Prozessgruppe, normalererweise zu der Prozessgruppe, zu der auch der Parentprozess gehört. Auch eine Prozessgruppe hat einen Group-Leader. Aber sie muß keinen haben, dh. sie kann den Prozess, der Group-Leader ist überleben. Vezwickt? Aber es kommt noch besser: Was ist die Aufgabe des Group-Leaders? Sie ist ja noch nichtmal, das er dasein muß. Also schicke ich dem Prozess, der Group-Leader ist, ein Signal z.B. mit kill, so beendet er sich, die Prozessgruppe bleibt aber weiter bestehen, und seine Childs, werden Prozess-No. 1 (init) untergeschoben. Also warum gibt es einen Group-Leader? Bekommt der Group-Leader ein Signal durch Benutzer-Eingriff (Strg-C etc.) gibt er dieses Signal an alle Prozesse der Prozessgruppe weiter. Das ist die einzige Aufgabe des Group-Leaders. Was ist ein Prozess? Einfach gesagt unter Linux: Alles. Was Kennzeichnet aber einen Prozess? Hauptsächlich 4 Dinge: 1. Er ist eindeutig zu identifizieren: pid 2. Er hat einen Parent: ppid 3. Er gehört einen Prozessgruppe an: pgid 4. Er gehört einer Session an: sid Beim beenden, schickt der Prozess seinem Parent ein Signal (SIGCHLD, No.: 17), das ist das Signal, auf das wait reagiert/wartet. Die resourcen des Child sind zu dem Zeitpunkt schon freigegeben und der Returncode steht in der Prozesstabelle. Dort kann er nun Abgeholt werden, das macht Normal der Parent, muß er aber nicht. Solange der Prozess noch in der Prozesstabelle steht, ist er ein "Zombi" oder auch defunct (unfunktional). Stirbt jetzt der Parent, geht Child an "Init" ... Man kann auch ein Programm schreiben, welches nachschaut welche pids von Zombies sind, und dann mit wait die entsprechenden pids abruft, auch so kann man Zombies entfernen, über Sinn oder Unsinn eines solchen Programms kann man streiten. Was passiert aber wenn ein Prozess "abnormal" beendet wird, auch dann entsteht gibt es ein SIGCHLD, nur was ist der Returncode? Der einzige der das beantworten kann ist der Kernel. Er weiß welches Signal an den Prozess geschickt wurde, und findet im Returncode des Prozesses nichts, so setzt er als Returncode das Signal ein. Schick ich dem Prozess mit kill ein Signal wird dieses als Returncode benutzt, das ist auch der einzige Unterschied zwischen Signalen die ich schicke (z. B. SIGSEGV) und einem vom Kernel erzeugtem, der Kernel weiß nichts davon. Literatur-Quellen: diverse Uralt Linuxbücher, Howtos etc. überall steht ein bischen drin, und: "Betriebssysteme und betriebssystemnahe Programmierung" Autor: Axel Rogat der Integrierten Arbeitsgruppe mathematische Probleme aus dem Ingenieurbereich Fachbereiche Mathematik, Bergische Universität Gesamthochschule - Wuppertal Februar 2000
2. Nachdem das Programm durchgelaufen ist und auch ein paar mal geforkt hat, beendet es sich ordnungsgemäß. Ein anschliessendes "ps faux" zeigt keine Prozesse mehr. Dann ist doch alles in Ordnung, oder?
Ja.
Für dich könnte das eine Rolle spielen, bei den fontlingen. Wielange muß der Prozeß immer wieder neu angeschmissen werden, er stürzt vieleicht 1mal ab, 16 mal 100 mal, bei 2000 Schriften 10.000 Schriften. Wie willst du das steuern? Mit ner Zufallszahl, Counter?
Das mit "Zufallszahl" verstehe ich jetzt nicht...
War ein Witz!
Steh ich auf'm Denkschlauch? Ich sehe einfach kein Problem mehr.
Ich auch nicht, wenn du weißt, was du machst, die Frage ist nur, brauchst du "setsid"? hth cu Gerald PS.: Sorry, für die Länge und sie teilweisen Wiederholungen.