[C] Processo pipe

Messaggioda giacomovicinanza » 14/05/2022, 10:26

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

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;
    }
}
giacomovicinanza
Junior Member
Junior Member
 
Messaggio: 123 di 218
Iscritto il: 18/08/2021, 15:55

Re: [C] Processo pipe

Messaggioda apatriarca » 14/05/2022, 10:35

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).
apatriarca
Moderatore
Moderatore
 
Messaggio: 5671 di 10436
Iscritto il: 08/12/2008, 20:37
Località: Madrid

Re: [C] Processo pipe

Messaggioda giacomovicinanza » 14/05/2022, 13:13

Ecco il codice aggiornato. Devo soltanto capire perchè non mi stampa i valori

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];

    /* 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;
    }
}
giacomovicinanza
Junior Member
Junior Member
 
Messaggio: 124 di 218
Iscritto il: 18/08/2021, 15:55

Re: [C] Processo pipe

Messaggioda apatriarca » 15/05/2022, 11:25

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.
apatriarca
Moderatore
Moderatore
 
Messaggio: 5672 di 10436
Iscritto il: 08/12/2008, 20:37
Località: Madrid


Torna a Informatica

Chi c’è in linea

Visitano il forum: Nessuno e 1 ospite