Pagina 1 di 3 1 2 3 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 24
  1. #1
    Utente di HTML.it
    Registrato dal
    Mar 2006
    Messaggi
    160

    [C] Problema con la fork()

    Ciao a tutti!!

    Devo scrivere un programmino che generi un certo numero, preso in input, di figli e ne aspetti solo uno prima di uscire. Io ho scritto questo codice:

    codice:
    #include <sys/wait.h>
    #include <stdio.h>
    #include <unistd.h>
    #include <stdlib.h>
    #include <string.h>
    
    int main(int argc, char *argv[]){
        pid_t pid;
        int status, children, i;
        if(argc!=2){
           printf("Usage: wait <number of children>");
           exit(1);
        }
        children=atoi(argv[1]);
        for(i=0; i<children; ++i){
           if((pid = fork()) < 0)
               perror("Fork failed");
           else if(pid == 0){
              printf("Sono il figlio e sto scrivendo qualcosa su stdout\n");
              exit(0);
           }
           else
              printf("Ho generato il figlio %d con pid %d\n",i+1,pid);
        }
        if(wait(&status) != pid){
           printf("Wait failed\n");
           exit(1);
        }
        printf("Uno dei miei figli ha finito, quindi finisco pure io\n");
        exit(0);
    }
    Il problema è che quando lo faccio partire mi stampa per n volte "Sono il figlio e sto scrivendo qualcosa su stdout" e poi il controllo if(wait(&status) != pid) fallisce. Non si sa chi verrà eseguito per primo se il figlio o il padre (infatti dipende dall'implementazione del sistema) ma a me sembra che venga eseguito sempre per primo il figlio. Come faccio a fare una cosa del genere?

    Grazie.

  2. #2
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284

    Re: [C] Problema con la fork()

    Originariamente inviato da Manugal
    Il problema è che quando lo faccio partire mi stampa per n volte "Sono il figlio e sto scrivendo qualcosa su stdout" e poi il controllo if(wait(&status) != pid) fallisce. Non si sa chi verrà eseguito per primo se il figlio o il padre (infatti dipende dall'implementazione del sistema) ma a me sembra che venga eseguito sempre per primo il figlio. Come faccio a fare una cosa del genere?
    La wait() aspetta la terminazione di uno qualunque dei figli ... in pratica il primo che termina. Quindi non puoi sapere a priori quale sarà.
    Ti basta testare se la wait() ha ritornato -1 (errore) oppure no.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  3. #3
    Utente di HTML.it
    Registrato dal
    Mar 2006
    Messaggi
    160
    Ok, ma secondo quel test alla fine, visto che fallisce, sembra che ritorni -1 (e non il pid del processo che è terminato), altrimenti non falliva o no? Quello che non mi spiego è perché fallisce?

  4. #4
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Originariamente inviato da Manugal
    Ok, ma secondo quel test alla fine, visto che fallisce, sembra che ritorni -1 (e non il pid del processo che è terminato), altrimenti non falliva o no? Quello che non mi spiego è perché fallisce?
    Allora innanzitutto stampa il valore di errno, includi <errno.h> e poi fai printf ("errno = %d\n", errno);

    Dimmi che valore di errno stampa e poi vediamo.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  5. #5
    Utente di HTML.it
    Registrato dal
    Mar 2006
    Messaggi
    160
    Allora la wait non mi ritorna -1 (e controllando errno, errno=0), però il comportamento del programma non è proprio quello che mi viene chiesto. Cioè a me viene chiesto che generi n figli, ma che aspetti anche solo un figlio che termini per poter terminare.

  6. #6
    Ti da errore perché quando fai il controllo pid contiene il valore dell'ultimo processo generato.
    Se il primo a terminare non è l'ultimo che hai creato allora entra nell'if. Fatto cosi ti va bene soltanto se termina per primo l'ultimo processo creato.

    Fai

    if (wait(&status)==-1)
    {
    printf("Wait error");
    exit 1;
    }
    exit 0;

    Dovrebbe funzionare credo

  7. #7
    Utente di HTML.it
    Registrato dal
    Mar 2006
    Messaggi
    160
    D'accordo può essere anche come dici tu (dato il particolare scheduling che implementa Linux che fa eseguire prima i figli e poi il padre). Il controllo che tu mi hai scritto mi è stato suggerito prima da andbin e in effetti non ritorna -1 (altrimenti qualcosa era andato storto). Il problema è che qui non è che va storto qualcosa (almeno sembra), ma che il programma non fa esattamente quello che dovrebbe fare (e cioè terminare appena termina un figlio, dopo averne generati un certo numero). Qui invece genera tutti i figli, li "esegue" e poi esegue il padre.

  8. #8
    prova con

    if (wait(&status)>0)
    exit(0);
    else
    exit(1);

    Il problema è per forza nel controllo che fa quell'if

    Siamo d'accordo che non ritorna -1, ma per il controllo che fai tu confronti il pid del processo terminato con il pid dell'ultimo processo che hai creato, il che molto probabilmente restituirà falso, eseguendo la exit(1);

    Può essere soltanto un problema di pid confrontati...

  9. #9
    Utente di HTML.it
    Registrato dal
    Mar 2006
    Messaggi
    160
    Ok, proverò. Però mi sorge il dubbio riguardo a dove ho posizionato quel controllo, perché avendolo posizionato lì è normale che verrà eseguito dopo aver fatto tutto o sbaglio?

  10. #10
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Ho fatto una piccola modifica al tuo programma (gli ho fatto stampare il pid nel figlio) e l'ho provato.
    Risultato:
    codice:
    Ho generato il figlio 1 con pid 29309
    Ho generato il figlio 2 con pid 29310
    Sono il figlio con pid 29309 e sto scrivendo qualcosa su stdout
    Sono il figlio con pid 29310 e sto scrivendo qualcosa su stdout
    Ho generato il figlio 3 con pid 29311
    Sono il figlio con pid 29311 e sto scrivendo qualcosa su stdout
    Sono il figlio con pid 29312 e sto scrivendo qualcosa su stdout
    Ho generato il figlio 4 con pid 29312
    Ho generato il figlio 5 con pid 29313
    Ho generato il figlio 6 con pid 29314
    Sono il figlio con pid 29313 e sto scrivendo qualcosa su stdout
    Sono il figlio con pid 29314 e sto scrivendo qualcosa su stdout
    Sono il figlio con pid 29315 e sto scrivendo qualcosa su stdout
    Ho generato il figlio 7 con pid 29315
    Ho generato il figlio 8 con pid 29316
    Ho generato il figlio 9 con pid 29317
    Sono il figlio con pid 29316 e sto scrivendo qualcosa su stdout
    Sono il figlio con pid 29317 e sto scrivendo qualcosa su stdout
    Sono il figlio con pid 29318 e sto scrivendo qualcosa su stdout
    Ho generato il figlio 10 con pid 29318
    Uno dei miei figli ha finito, quindi finisco pure io
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.