fork () e wait () con due processi figlio

Devo usare le funzioni fork () e wait () per completare un compito. Stiamo modellando un comportamento non deterministico e abbiamo bisogno che il programma si biforchi () se c’è più di una ansible transizione.

Per cercare di capire come forchetta e aspettare lavoro, ho appena creato un programma semplice. Penso di capire ora come funzionano le chiamate e andrebbe bene se il programma si diramasse solo una volta perché il processo genitore potrebbe utilizzare lo stato di uscita dal processo figlio singolo per determinare se il processo figlio ha raggiunto o meno lo stato di accettazione.

Come puoi vedere dal codice che segue, però, voglio essere in grado di gestire le situazioni in cui devono essere presenti più processi figlio. Il mio problema è che sembra che tu sia in grado di impostare lo stato solo usando una funzione _exit una volta. Pertanto, come nel mio esempio, lo stato di uscita verificato dal processo padre per indica che il primo processo figlio ha emesso 0 come stato di uscita, ma non ha informazioni sul secondo processo figlio.

Ho provato semplicemente non _exit () – su un rifiuto, ma poi quel processo figlio avrebbe continuato, e in effetti sembrerebbe che ci siano due processi genitore.

Ci scusiamo per le chiacchiere, ma sarei grato se qualcuno potesse dirmi come il mio processo genitore potrebbe ottenere le informazioni sullo stato su più di un processo figlio, o sarei felice che il processo genitore si accorga solo dell’accettazione dello stato dai processi figli, ma in tal caso avrei bisogno di uscire dai processi figli che hanno uno stato di rifiuto.

Il mio codice di prova è il seguente:

#include  #include  #include  #include  #include  int main(void) { pid_t child_pid, wpid, pid; int status = 0; int i; int a[3] = {1, 2, 1}; for(i = 1; i < 3; i++) { printf("i = %d\n", i); pid = getpid(); printf("pid after i = %d\n", pid); if((child_pid = fork()) == 0) { printf("In child process\n"); pid = getpid(); printf("pid in child process is %d\n", pid); /* Is a child process */ if(a[i]  0) { /* Is the parent process */ pid = getpid(); printf("parent_pid = %d\n", pid); wpid = wait(&status); if(wpid != -1) { printf("Child's exit status was %d\n", status); if(status > 0) { printf("Accept\n"); } else { printf("Complete parent process\n"); if(a[0] < 2) { printf("Accept\n"); } else { printf("Reject\n"); } } } } return 0; } 

Mi sembra che il problema di base sia che hai una chiamata wait() piuttosto che un ciclo che aspetta finché non ci sono più bambini. Inoltre, si attende solo se l’ultimo fork() esito positivo anziché se almeno un fork() esito positivo.

Dovresti utilizzare _exit() se non vuoi eseguire normali operazioni di pulizia, come lo svuotamento di flussi di file aperti incluso lo stdout . Ci sono occasioni per usare _exit() ; questo non è uno di loro. (In questo esempio, potresti anche semplicemente far tornare i figli invece di chiamare exit() direttamente perché il ritorno da main() equivale a uscire con lo stato restituito. Tuttavia, molto spesso si farebbe il biforcarsi e così via in una funzione diversa da main() , e quindi exit() è spesso appropriato).


Hacked, versione semplificata del tuo codice che fornisce la diagnostica che vorrei. Si noti che il ciclo for saltato il primo elemento dell’array (il mio no).

 #include  #include  #include  #include  int main(void) { pid_t child_pid, wpid; int status = 0; int i; int a[3] = {1, 2, 1}; printf("parent_pid = %d\n", getpid()); for (i = 0; i < 3; i++) { printf("i = %d\n", i); if ((child_pid = fork()) == 0) { printf("In child process (pid = %d)\n", getpid()); if (a[i] < 2) { printf("Should be accept\n"); exit(1); } else { printf("Should be reject\n"); exit(0); } /*NOTREACHED*/ } } while ((wpid = wait(&status)) > 0) { printf("Exit status of %d was %d (%s)\n", (int)wpid, status, (status > 0) ? "accept" : "reject"); } return 0; } 

Esempio di output (MacOS X 10.6.3):

 parent_pid = 15820 i = 0 i = 1 In child process (pid = 15821) Should be accept i = 2 In child process (pid = 15822) Should be reject In child process (pid = 15823) Should be accept Exit status of 15823 was 256 (accept) Exit status of 15822 was 0 (reject) Exit status of 15821 was 256 (accept) 

Metti la tua funzione wait () in un ciclo e attendi tutti i processi figli. La funzione wait restituirà -1 e errno sarà uguale a ECHILD se non sono disponibili altri processi figli.

brillante esempio Jonathan Leffler, per far funzionare il tuo codice su SLES, avevo bisogno di aggiungere un’intestazione aggiuntiva per consentire l’object pid_t 🙂

 #include