Fork vs PID

Post Reply
Message
Author
User avatar
AlPhedo
Posts: 5
Joined: 23. Jun 2006 2:23

Fork vs PID

#1 Post by AlPhedo »

Hi,

ich hab mir ein kleines Programm geschrieben, mit dem über fork() Prozesse erzeugt werden und über getpid() die Prozessnummer ausgegeben wird.
Alledings hab ich mir ein paar Tips holen müssen und verstehe es irgendwie noch nicht so.
Hier ist der Quellcode:

Code: Select all

#include <stdio.h>

int main&#40;&#41;
&#123;
int kind = 3;
int enkel =2;
int i,j,pid,kind_pid;

for &#40;i=0;i<kind;i++&#41;
&#123;
	pid = fork&#40;&#41;;
	if &#40;pid == 0&#41;
	&#123;
		kind_pid = getpid&#40;&#41;;
		printf&#40;"\n PID von Kind&#58; %d\n",kind_pid&#41;;
	
		for &#40;j=0;j<enkel;j++&#41;
		&#123;	
			pid= fork&#40;&#41;;
			if &#40;pid == 0&#41;
			&#123;
			printf&#40;"\n PID von Enkel %d des Kindes %d\n",getpid&#40;&#41;,kind_pid&#41;;
			break;  // <<<<---*****_____---------------  HIER nr1
			&#125;
		&#125;	
		break; // <<<<---*****_____---------------  HIER nr2
	&#125;
&#125;	
&#125;
Wieso genau muss das break; jeweils in die if-Bedingung?? die Schleife regelt doch die Anzahl?? Aber wenn ich das break weg lasse - ist die Ausgabe total wirr!!!

Meine andere Frage : wenn ich das Prg über die Bash kompiliere und ausführe: ist die Ausgabe zwar korrekt ABER die Eingabezeile taucht mitten in der Ausgabe des Programms auf -- wieso das passiert, kann ich echt nicht nachvollziehen?!?!?!

mfG
AlPhedp

User avatar
Janka
Posts: 3585
Joined: 11. Feb 2006 19:10

Re: Fork vs PID

#2 Post by Janka »

AlPhedo wrote: Wieso genau muss das break; jeweils in die if-Bedingung?? die Schleife regelt doch die Anzahl?? Aber wenn ich das break weg lasse - ist die Ausgabe total wirr!!!
Um das Prinzip besser zu verstehen lässt du besser erstmal alles weg, was mit den Enkeln zu tun hat. Es bleibt:

Code: Select all

#include <stdio.h> 
#include <sys/types.h>
#include <unistd.h>
 
int main&#40;&#41; 
&#123; 
  int kind = 3; 
  int i,pid,kind_pid; 
 
  for &#40;i=0;i<kind;i++&#41; 
  &#123; 
    pid = fork&#40;&#41;; 
    if &#40;pid == 0&#41; 
    &#123; 
      kind_pid = getpid&#40;&#41;; 
      printf&#40;"\n PID von Kind&#58; %d\n",kind_pid&#41;; 
   
      break; // <<<<---*****_____---------------  HIER nr2 
    &#125; 
  &#125;    
&#125;
Das break wird gebraucht, weil ja nach dem fork() *zwei* Prozesse dasselbe Programm ausführen. Es gibt jeweils den Kind-Teil, der in den then-Teil des if-Blocks reinläuft, und halt den Vater-Teil, der daran vorbeiläuft. Der Kind-Teil soll ja nicht erneut fork() aufrufen, also braucht er das break, um aus der Schleife auszubrechen und sich dann zu Beenden.
Meine andere Frage : wenn ich das Prg über die Bash kompiliere und ausführe: ist die Ausgabe zwar korrekt ABER die Eingabezeile taucht mitten in der Ausgabe des Programms auf -- wieso das passiert, kann ich echt nicht nachvollziehen?!?!?!
Weil die Kindprozesse weiterlaufen, auch wenn der Vaterprozess beendet wurde. Die Bash kommt also zurück, aber die Kindprozesse laufen noch, erzeugen also noch Ausgaben in dasselbe tty.

Janka
Ich vertonne Spam immer in /dev/dsp statt /dev/null.
Ich mag die Schreie.

User avatar
AlPhedo
Posts: 5
Joined: 23. Jun 2006 2:23

#3 Post by AlPhedo »

sehr sehr seltsam die fork() .... aber ich glaube ich habe es jetzt soweit.

kann man es eigentlich verhindern, dass das Eingabeprompt in der Ausgabe erscheint?

viele Grüße
AlPhedo

User avatar
Janka
Posts: 3585
Joined: 11. Feb 2006 19:10

#4 Post by Janka »

Nein, fork() ist nicht seltsam. fork() ist halt fork(). Du willst, dass *ein* Programm ab einem bestimmten Punkt *zweimal gleichzeitig* ausgeführt wird. Das ist fork. Und damit die beiden Teile unterschiedliche Wege nehmen können (sonst wäre das ganze ja ziemlich sinnlos) bekommen Vater und Kindprozess halt *unterschiedliche* Werte aus dem fork() raus.

Der Rest ist gleich -- logisch, denn beide Prozesse teilen sich ja die ganze Zeit über dieselbe Codebasis.

Wenn du *danach* z.B. dem Kind eine neue Codebasis geben willst (neues Programm starten), muss du *danach* execve() etc. benutzen.

"Neues Programm" ist unter Unix immer die Paarung fork() + execve().
kann man es eigentlich verhindern, dass das Eingabeprompt in der Ausgabe erscheint?
Man kann (sollte) im Vater-Zweig einen wait() oder waitpid()-Aufruf machen. Dann wird der Vater angehalten, bis ein Kind beendet wird.

Janka
Ich vertonne Spam immer in /dev/dsp statt /dev/null.
Ich mag die Schreie.

User avatar
AlPhedo
Posts: 5
Joined: 23. Jun 2006 2:23

#5 Post by AlPhedo »

alles klar vielen Dank!!!!!!!!!!!!!!!

viele Grüße AlPhedo

Post Reply