Fork vs PID

Antworten
Nachricht
Autor
Benutzeravatar
AlPhedo
Beiträge: 5
Registriert: 23. Jun 2006 2:23

Fork vs PID

#1 Beitrag von AlPhedo » 24. Jun 2006 12:55

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: Alles auswählen

#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

Benutzeravatar
Janka
Beiträge: 3585
Registriert: 11. Feb 2006 19:10

Re: Fork vs PID

#2 Beitrag von Janka » 24. Jun 2006 14:29

AlPhedo hat geschrieben: 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: Alles auswählen

#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.

Benutzeravatar
AlPhedo
Beiträge: 5
Registriert: 23. Jun 2006 2:23

#3 Beitrag von AlPhedo » 25. Jun 2006 12:04

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

Benutzeravatar
Janka
Beiträge: 3585
Registriert: 11. Feb 2006 19:10

#4 Beitrag von Janka » 25. Jun 2006 15:42

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.

Benutzeravatar
AlPhedo
Beiträge: 5
Registriert: 23. Jun 2006 2:23

#5 Beitrag von AlPhedo » 25. Jun 2006 17:58

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

viele Grüße AlPhedo

Antworten