2013-03-07 5 views
5

Also habe ich Code hier, und ich erwartete, dass es strikt ls -l 5 mal laufen, aber es scheint viel öfter laufen. Was mache ich hier falsch? Ich möchte ls 5 mal laufen, also gabele ich 5 mal. Vielleicht verstehe ich das Konzept des Wartens nicht richtig? Ich habe eine Menge Tutorials durchgelesen, und keiner scheint mehrere Prozesse mit fork zu bewältigen.Warum verzweifle ich hier mehr als 5 mal?

#include <stdio.h> 
#include <stdlib.h> 
#include <sys/types.h> 
#include <sys/wait.h> 
#include <unistd.h> 

int main() 
{ 
    pid_t pidChilds[5]; 

    int i =0; 

    for(i = 0; i<5; i++) 
    { 
     pid_t cpid = fork(); 
     if(cpid<0) 
      printf("\n FORKED FAILED"); 
     if(cpid==0) 
      printf("FORK SUCCESSFUL"); 
     pidChilds[i]=cpid; 
    } 





} 
+2

Tipp: Wenn cpid == 0, glaubst du, dass du sonst noch etwas vergessen hast? –

+0

@NicholasWilson Nicht, dass ich mir vorstellen kann. :(Was mache ich falsch? – NoNameY0

+0

Forkbomb, ftw!: D – Carsten

Antwort

2

Wenn Sie fork in C verwenden, müssen Sie sich vorstellen, dass der Prozesscode und der Status in einen neuen Prozess kopiert werden. Ab diesem Zeitpunkt beginnt die Ausführung dort, wo sie unterbrochen wurde.

Wenn Sie exec in C verwenden, müssen Sie sich vorstellen, dass der gesamte Prozess ersetzt wird, wenn der Aufruf erfolgreich ist.

Hier ist Ihr Code, neu geschrieben, um das erwartete Verhalten zu erzeugen. Bitte lesen Sie die Kommentare.

#include <stdio.h> 
#include <stdlib.h> 
#include <sys/types.h> 
#include <sys/wait.h> 
#include <unistd.h> 

int main() 
{ 
    pid_t cpid; 
    pid_t pidChildren[5]; 

    int i; 
    for (i = 0; i < 5; i++) 
    { 
     cpid = fork(); 
     if (cpid < 0) { 
      printf("fork failed\n"); 
     } else if (cpid == 0) { 
      /* If we arrive here, we are now in a copy of the 
       state and code of the parent process. */ 
      printf("fork successful\n"); 
      break; 
     } else { 
      /* We are still in the parent process. */ 
      pidChildren[i] = cpid; 
     } 
    } 

    if (cpid == 0) { 
     /* We are in one of the children; 
      we don't know which one. */ 
     char *cmd[] = {"ls", "-l", NULL}; 
     /* If execvp is successful, this process will be 
      replaced by ls. */ 
     if (execvp(cmd[0], cmd) < 0) { 
      printf("execvp failed\n"); 
      return -1; 
     } 
    } 

    /* We expect that only the parent arrives here. */ 
    int exitStatus = 0; 
    for (i = 0; i < 5; i++) { 
     waitpid(pidChildren[i], &exitStatus, 0); 
     printf("Child %d exited with status %d\n", i, exitStatus); 
    } 

    return 0; 
} 
+0

Dieses Array ist nutzlos für jedes Kind, das bald 'ls' wird. Wenn' cpid! = 0' bei An diesem Punkt wissen wir, dass wir uns im übergeordneten Prozess befinden, der die einzige Kopie dieses Programms ist, die dieses Array wirklich füllen muss.Fünf Kopien des obigen Codes werden im Speicher erstellt, nur einer von ihnen ist der Elternteil, wo die "Hauptarbeit" erledigt wird. – OregonTrail

+0

Angenommen, Sie möchten 5 verschiedene Befehle nacheinander ausführen, d. H. Ls, dann ls -l, dann pwd, warum funktioniert das nicht für Ihren Code? – NoNameY0

+0

Angenommen, Sie möchten 5 verschiedene Befehle nacheinander ausführen, d. H. Ls, dann ls -l, dann pwd, warum funktioniert das nicht für Ihren Code? – NoNameY0

3

Sie verzweigen sich in einer Schleife und verzweigen den Prozess mit dem Anweisungszeiger quasi.

Bedeutung: ZB Ihr erster Kind-Prozess wird sich in einer Schleife finden, die noch 4 Runden zu gehen hat.

Und jeder der 4 Prozesse , die Prozess Spawns finden wird, muss es 3 Runden mehr gehen.

Und so weiter.

fork() Gibt zurück, ob der Prozess, in dem Sie sich befinden, der Eltern- oder Kindprozess ist. Sie sollten diesen Rückgabewert überprüfen und break; die Schleife, wenn Sie in einem Child-Prozess sind.

"Bei Erfolg wird die PID des untergeordneten Prozesses im übergeordneten und 0 im untergeordneten zurückgegeben. Bei einem Fehler wird -1 im übergeordneten zurückgegeben, kein untergeordneten Prozess erstellt und errno ist entsprechend einstellen. "

Sie sollten also if(cpid==0) break;.

+0

nicht 120 heute, läuft es etwa 15-20 mal. Ich bin streng speichern die pid in den kind prozess. Wie kann ich mein problem beheben? Für jedes form, es gibt 1 Kindprozess, und im Kindprozess speichere ich das pid – NoNameY0

+0

nicht genau 120? wissen Sie nicht warum, aber die ** Lösung ** ist klar. –

+1

Ich denke nicht, dass Ihre Berechnung korrekt ist. Die Anzahl der Prozesse verdoppelt sich bei jeder Iteration, also sollte es insgesamt 1 + 2 + 4 + 8 + 16 = 31 Ausführungen des ls Befehls sein .. –

0

Jeder i ‚th fork beginnt innerhalb der Schleife, so wird es die restlichen n-i Iterationen dieser Schleife laufen, rekursiv gabeln.

+0

Ich habe es in der Schleife, da ich erwarte, 5 Gabeln zu haben, deren Kinder die pid im kindlichen pid-Feld für die weitere Arbeit speichern sollten – NoNameY0

+0

Warum das Downvote? –

Verwandte Themen