2009-05-18 8 views
13

qualcuno mi può aiutare su come creare più processi figlio che hanno lo stesso genitore per fare "parte" di un particolare lavoro?Processo figlio multiplo

ad esempio, un algoritmo di ordinamento esterno che viene applicato con processi figlio; ogni processo figlio ordina una parte dei dati e, infine, il genitore li unisce ..

EDIT: Forse dovrei parlare dei biforcano processi multipli bambino con anello ..

+0

non sarebbe meglio con le discussioni? – AviD

+0

beh, potrebbe essere giusto .. ma ho bisogno di praticare il forking multiplo() che significa più processi figlio .. – israkir

risposta

3

È possibile farlo con fork. Un dato genitore può sborsare tutte le volte che vuole. Tuttavia, sono d'accordo con AviD pthreads potrebbe essere più appropriato.

pid_t firstChild, secondChild; 
firstChild = fork(); 
if(firstChild > 0) 
{ 
    // In parent 
    secondChild = fork(); 
    if(secondChild > 0) 
    { 
    // In parent 
    } 
    else if(secondChild < 0) 
    { 
    // Error 
    } 
    else 
    { 
    // In secondChild 
    } 
} 
else if(firstChild < 0) 
{ 
    // Error 
} 
else 
{ 
    // In firstChild 
} 
+0

non dovremmo considerare anche il caso, dove xxxChild <0 genererà un errore? Penso che (xxxChild> 0) sarà più appropriato ... – CHANist

+0

@CHANist, grazie, dovrebbe essere coperto ora. –

38

Ecco come forcella 10 i bambini e attendere per loro di finire:

pid_t pids[10]; 
int i; 
int n = 10; 

/* Start children. */ 
for (i = 0; i < n; ++i) { 
    if ((pids[i] = fork()) < 0) { 
    perror("fork"); 
    abort(); 
    } else if (pids[i] == 0) { 
    DoWorkInChild(); 
    exit(0); 
    } 
} 

/* Wait for children to exit. */ 
int status; 
pid_t pid; 
while (n > 0) { 
    pid = wait(&status); 
    printf("Child with PID %ld exited with status 0x%x.\n", (long)pid, status); 
    --n; // TODO(pts): Remove pid from the pids array. 
} 
+1

in realtà non ho avuto la seconda parte (aspetto che i bambini escano) .. cosa significa status? è una proprietà del processo figlio? – israkir

+0

Status è lo stato di uscita del processo figlio. Dipende dal valore di uscita (...), o se il processo viene ucciso da un segnale, quindi dipende dal numero del segnale. Vedi questo per ulteriori informazioni: http://linux.die.net/man/2/wait – pts

+0

una domanda, stai biforcando dallo stesso genitore root o da ogni bambino? –

5

penso che sarebbe la pena sottolineare il motivo per cui le discussioni sono più appropriato qui:

Come sei cercando di fare una "parte" del lavoro in parallelo presumo che il tuo programma abbia bisogno di conoscere il risultato del calcolo. fork() s di un processo non condivide più delle informazioni iniziali dopo fork(). Ogni cambiamento in un processo non è noto all'altro e sarà necessario passare le informazioni come un messaggio (ad esempio attraverso un tubo, vedere "man pipe"). I thread in un processo condividono lo stesso spazio dell'indirizzo e quindi sono in grado di manipolare i dati e renderli visibili a tutti gli altri "immediatamente". Aggiungendo anche i vantaggi di essere più leggero, vorrei andare con pthreads().

Dopo tutto: imparerai tutto ciò che devi sapere su fork() se usi comunque pthreads.

+0

D'altro canto, se * work * è fornito dall'utente, si vorrebbe farlo in un nuovo processo per la protezione da crash. –

1

Se si desidera avviare più fork, è necessario farlo in modo ricorsivo. Questo perché devi chiamare fork dal processo padre. Altrimenti, se avvii un secondo fork, duplicherai sia il processo genitore che il processo figlio. Ecco un esempio:

void forker(int nprocesses) 
{ 
    pid_t pid; 

    if(nprocesses > 0) 
    { 
     if ((pid = fork()) < 0) 
     { 
      perror("fork"); 
     } 
     else if (pid == 0) 
     { 
      //Child stuff here 
      printf("Child %d end\n", nprocesses); 
     } 
     else if(pid > 0) 
     { 
      //parent 
      forker(nprocesses - 1); 
     } 
    } 
}