2013-03-07 1 views
5

Quindi ho il codice qui, e mi aspettavo che eseguisse rigorosamente ls -l 5 volte, ma sembra che funzioni molto più volte. Cosa sto facendo di sbagliato qui? Voglio eseguire ls 5 volte, quindi forzo 5 volte. Forse non capisco il concetto di aspettare correttamente? Sono andato oltre una tonnellata di tutorial, e nessuno sembra affrontare più processi utilizzando a fondo la forcella.Perché sto biforcando più di 5 volte qui?

#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

Suggerimento: se cpid == 0, pensi che ci sia qualcos'altro che hai dimenticato di fare? –

+0

@NicholasWilson Non che io possa pensare. :(Che cosa sto sbagliando? – NoNameY0

+0

Forkbomb, ftw!: D – Carsten

risposta

2

Quando si utilizza la forcella in C, è necessario immaginare il codice e lo stato del processo da copiare in un nuovo processo, a quel punto inizia l'esecuzione dal punto in cui era stato interrotto.

Quando si utilizza exec in C, è necessario immaginare che l'intero processo venga sostituito se la chiamata ha esito positivo.

Ecco il codice, riscritto per produrre il comportamento previsto. Si prega di leggere i commenti.

#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

Questo array è inutile per ogni bambino, che diventerà presto 'ls'. Se' cpid! = 0' a quel punto, allora sappiamo che siamo nel processo genitore, che è l'unica copia di questo programma che ha davvero bisogno di popolare quella matrice.Cinque copie del codice sopra saranno fatte in memoria, solo una di queste è la genitrice in cui viene eseguito il "master work". – OregonTrail

+0

supponiamo di voler eseguire 5 diversi comandi back to back, cioè ls, quindi ls -l quindi pwd, perché non funziona il codice? – NoNameY0

+0

supponiamo di voler eseguire 5 diversi comandi back to back, vale a dire ls, quindi ls -l then pwd, perché non funziona per il tuo codice? – NoNameY0

3

Si sta biforcandosi in un ciclo e la forcella quasi-copia il processo incluso il puntatore di istruzioni.

Significato: Ad esempio, il primo processo figlio si troverà in un ciclo che ha ancora 4 round da percorrere.

E ciascuno dei 4 processi che lo spawn di processo troverà deve andare 3 round in più.

E così via.

fork() restituisce se il processo in cui ci si trova è il processo padre o figlio. È necessario verificare il valore restituito e il ciclo break; se si è in un processo figlio.

"In caso di esito positivo, il PID del processo figlio viene restituito nel padre e 0 viene restituito nel figlio. In caso di errore, -1 viene restituito nel padre, nessun processo figlio viene creato e errno è impostato in modo appropriato. "

Quindi è necessario if(cpid==0) break;.

+0

non 120 di oggi, funziona circa 15-20 volte. Sto memorizzando rigorosamente il pid nel processo figlio.Come posso risolvere il mio problema? Per ogni modulo, c'è 1 processo figlio e nel processo figlio sto memorizzando il pid – NoNameY0

+0

non esattamente 120? Non so perché, ma la ** soluzione ** è chiara. –

+1

Non penso che il tuo calcolo sia corretto. si raddoppia ad ogni iterazione, quindi dovrebbe essere un totale di 1 + 2 + 4 + 8 + 16 = 31 esecuzioni del comando ls. –

0

Ogni i 'th fork inizia all'interno del ciclo, in modo che verrà eseguito i restanti n-i iterazioni di quel ciclo, che si biforcano in modo ricorsivo.

+0

lo ho nel loop dal momento che mi aspetto di avere 5 fork, i cui figli dovrebbero memorizzare il pid nell'array pid figlio per ulteriori lavori – NoNameY0

+0

Perché il downvote? –