[C] Processo pipe
Salve a tutti. Sto riscontrando un problema con questo esercizio praticamente nel momento in cui arrivo nel processo padre mi stampa messaggio incompleto pur inserendo un valore intero come richiesto dalla traccia. L'ho visionato con cura prestando attenzione a tutto eppure mi sfugge qualcosa. Grazie mille a chi mi aiuterà.
https://onlinegdb.com/vaWbnDncc -> il link del codice
https://onlinegdb.com/vaWbnDncc -> il link del codice
/***************************************************************** Il candidato completi il programma fornito, implementando il main. Il programma crea un processo figlio; il processo figlio legge da tastiera un numero intero N >= 0, e trasmette al processo padre mediante una pipe i valori N, N-1, N-2, N-3, ..., 0 (incluso). Il processo padre legge dalla pipe i valori trasmessi dal processo figlio e li stampa, finche' non riceve il valore 0; dopodiche' il processo padre attende la terminazione del processo figlio e termina. Esempio: Sono il processo figlio. Inserisci un numero >=0: 4 Sono il processo padre. Ho ricevuto: 4 Sono il processo padre. Ho ricevuto: 3 Sono il processo padre. Ho ricevuto: 2 Sono il processo padre. Ho ricevuto: 1 Sono il processo padre. Ho ricevuto: 0 Sono il processo padre. Il figlio ha terminato. ******************************************************************/ #include <stdio.h> #include <stdlib.h> #include <math.h> #include <unistd.h> #include <sys/wait.h> int main(int argc, char *argv[]) { int fd[2]; int N; /* Creazione della pipe */ if(pipe(fd) < 0){ printf("Errore nella creazione pipe\n"); return -1; } pid_t pid = fork(); // la chiamata fork crea un processo figlio /* Il codice a seguire viene eseguito da entrambi i processi: padre e figlio */ if(pid < 0) { /* Errore verificato */ printf("Fork non riuscita\n"); return -1; } else if(pid == 0) { /* Processo Figlio */ close(fd[0]); // Non interessato a leggere /* Preparazione del messaggio */ printf("Sono il processo figlio. Inserisci un numero interno >= 0: "); scanf("%d", &N); if(N < 0){ return -1; } int array[N]; for(int i = 0; i <= N; i++){ array[i] = i; } /* Inviare il messaggio */ int inviati = write(fd[1], array, N*sizeof(int)); if(inviati != sizeof(array)) { printf("Errore nell'invio\n"); return -1; } close(fd[1]); return 0; } else { /* Processo Padre */ close(fd[1]); // Non interessato a scrivere int array[N]; int ricevuti = read(fd[0], &array, N*sizeof(int)); if(ricevuti < 0) { printf("Errore nella ricezione\n"); } else if(ricevuti < sizeof(array)) { printf("Messaggio incompleto\n"); } else { printf("Numeri ricevuti: "); int i; for(i=N; i>=0; i--) { printf("%d", array[i]); printf("\n"); } } close(fd[0]); return 0; } }
Risposte
Nel processo padre non hai alcuna idea di quale sia il numero che è stato letto dal processo figlio e quindi certamente non puoi sapere quanti byte leggere o quanto grosso creare il tuo array (la cui dimensione quindi dipende da un valore non inizializzato!!). Dovrai insomma leggere i valori passati dal processo figlio in un ciclo finché non ricevi il valore 0. Probabilmente non userei l'array neanche nel processo figlio (nota che la dimensione dell'array dovrebbe essere N+1.. in ogni caso).
Ecco il codice aggiornato. Devo soltanto capire perchè non mi stampa i valori
/***************************************************************** Il candidato completi il programma fornito, implementando il main. Il programma crea un processo figlio; il processo figlio legge da tastiera un numero intero N >= 0, e trasmette al processo padre mediante una pipe i valori N, N-1, N-2, N-3, ..., 0 (incluso). Il processo padre legge dalla pipe i valori trasmessi dal processo figlio e li stampa, finche' non riceve il valore 0; dopodiche' il processo padre attende la terminazione del processo figlio e termina. Esempio: Sono il processo figlio. Inserisci un numero >=0: 4 Sono il processo padre. Ho ricevuto: 4 Sono il processo padre. Ho ricevuto: 3 Sono il processo padre. Ho ricevuto: 2 Sono il processo padre. Ho ricevuto: 1 Sono il processo padre. Ho ricevuto: 0 Sono il processo padre. Il figlio ha terminato. ******************************************************************/ #include <stdio.h> #include <stdlib.h> #include <math.h> #include <unistd.h> #include <sys/wait.h> int main(int argc, char *argv[]) { int fd[2]; /* Creazione della pipe */ if(pipe(fd) < 0){ printf("Errore nella creazione pipe\n"); return -1; } pid_t pid = fork(); // la chiamata fork crea un processo figlio /* Il codice a seguire viene eseguito da entrambi i processi: padre e figlio */ if(pid < 0) { /* Errore verificato */ printf("Fork non riuscita\n"); return -1; } else if(pid == 0) { /* Processo Figlio */ close(fd[0]); // Non interessato a leggere /* Preparazione del messaggio */ int N; printf("Sono il processo figlio. Inserisci un numero interno >= 0: "); scanf("%d", &N); if(N < 0){ return -1; } int array[N+1]; for(int i = 0; i < N; i++){ array[i] = i; } /* Inviare il messaggio */ int inviati = write(fd[1], array, sizeof(int)); if(inviati != sizeof(N)) { printf("Errore nell'invio\n"); return -1; } close(fd[1]); return 0; } else { /* Processo Padre */ close(fd[1]); // Non interessato a scrivere int N; int array[N+1]; int ricevuti = read(fd[0], &array, sizeof(N)); if(ricevuti < 0) { printf("Errore nella ricezione\n"); } else if(ricevuti < sizeof(N)) { printf("Messaggio incompleto\n"); } else { printf("Numeri ricevuti: "); int i; for(i=N-1; i>=0; i--) { printf("%d", array[i]); printf("\n"); } } close(fd[0]); return 0; } }
Non mi sembra tu abbia corretto l'errore relativo all'uso di N non inizializzata nel processo padre. Variabile che certamente non avrà lo stesso valore letto nel processo figlio.. Devi leggere un intero per volta fino a leggere il valore zero.