Comunicazione tra processi in C usando due pipe

Linguaggi di programmazione: php, perl, python, C, bash e tutti gli altri.
Tino-Tom
Prode Principiante
Messaggi: 68
Iscrizione: venerdì 29 agosto 2014, 13:00
Distribuzione: Ubuntu 64bit

Comunicazione tra processi in C usando due pipe

Messaggio da Tino-Tom »

Ciao a tutti, sto cercando di scrivere il mio programma in C con pipe. Ho tre processi: P (padre), R (figlio) e W (figlio).
P e R comunicano tramite la prima pipe. P e W comunicano tramite la seconda pipe. Il figlio R legge il file di input, passando ogni riga al padre P. Il padre P legge le parole e controlla se sono palindrome, se la parola è palindroma, il padre la invia al figlio W. Il figlio W deve semplicemente stampare le parole ricevute.

ecco il codice

Codice: Seleziona tutto

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/wait.h>

#define DIMBUF 1024

int palindroma(const char *stringa)
{
    int len = strlen(stringa);

    int j = 0;
    for (int i = len - 1; i >= 0; i--)
    {
        if (stringa[i] == stringa[j])
        {
            j++;
        }
        else
            return 0;
    }
    return 1;
}

void child_r(int piper, const char *filename, char tmp[DIMBUF])
{
    FILE *w_stream, *file;

    if ((w_stream = fdopen(piper, "w")) == NULL)
    {
        perror("writer piper_rp");
        exit(1);
    }

    printf("Sono il figlio R\n");

    if ((file = fopen(filename, "r")) == NULL)
    {
        perror("apertura file");
        exit(1);
    }

    while (fgets(tmp, DIMBUF, file) != NULL)
    {
        printf("\tLeggo dal file: %s", tmp);
        fputs(tmp, w_stream);
    }
    fclose(file);
    fclose(w_stream);
}

void child_w(int piper, char tmp[DIMBUF])
{
    FILE *r_stream;

    if ((r_stream = fdopen(piper, "r")) == NULL)
    {
        perror("reader");
        exit(1);
    }

    while (fgets(tmp, DIMBUF, r_stream) != NULL)
    {
        printf("\tMessaggio ricevuto: %s\n", tmp);
    }

    fclose(r_stream);
    exit(0);
}

void father(int piper_rp, char tmp[DIMBUF], int piper_pw)
{

    FILE *r_stream, *w_stream;
    int len;

    if ((r_stream = fdopen(piper_rp, "r")) == NULL)
    {
        perror("reader");
        exit(1);
    }

    if ((w_stream = fdopen(piper_pw, "w")) == NULL)
    {
        perror("writer piper_pw");
        exit(1);
    }

    while (fgets(tmp, DIMBUF, r_stream) != NULL)
    {
        len = strlen(tmp);
        if (tmp[len - 1] == '\n')
            tmp[len - 1] = 0;

        int pal = palindroma(tmp);

        if (pal)
        {
            printf("\tMessaggio inviato: %s\n", tmp);
            fputs(tmp, w_stream);
        }
    }

    fclose(w_stream);
    fclose(r_stream);
}

int main(int argc, char const *argv[])
{
    /* code */

    int piper_rp[2];
    int piper_pw[2];
    char tmp[DIMBUF];
    const char *filename = argv[1];

    if (argc != 2)
    {
        fprintf(stderr, "Utilizzo %s file.txt \n ", argv[0]);
        exit(1);
    }

    if (pipe(piper_pw) == -1)
    {
        perror("errore pipe_pw");
        exit(1);
    }

    if (pipe(piper_rp) == -1)
    {
        perror("errore pipe_rp");
        exit(1);
    }

    if (fork() == 0)
    {
        close(piper_rp[0]);
        child_r(piper_rp[1], filename, tmp);
    }
    else
    {

        // padre
        sleep(1);
        close(piper_rp[1]);
        close(piper_pw[0]);
        printf("\nSono il padre P\n");
        father(piper_rp[0], tmp, piper_pw[1]);

        if (fork() == 0)
        {
            printf("\nSono il figlio W\n");
            close(piper_pw[1]);
            child_w(piper_pw[0], tmp);
        }
        else
            wait(NULL);
    }

    return 0;
}

Ecco l'output:

Codice: Seleziona tutto

Sono il figlio R
        Leggo dal file: Ciao
        Leggo dal file: Mondo
        Leggo dal file: Ale
        Leggo dal file: emme
        Leggo dal file: piip
        Leggo dal file: veffev
        Leggo dal file: Scatola
        Leggo dal file: computer
        Leggo dal file: america
        Leggo dal file: abba
        Leggo dal file: acca
        Leggo dal file: cielo
        Leggo dal file: lampada
        Leggo dal file: effe
Sono il padre P
        Messaggio inviato: emme
        Messaggio inviato: piip
        Messaggio inviato: veffev
        Messaggio inviato: abba
        Messaggio inviato: acca
        Messaggio inviato: effe
Perché il figlio W non ha un output? Perché il programma non entra mai al secondo fork? Non riesco a capirlo. Qualcuno potrebbe aiutarmi ? :muro: :ciao:
gila75
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 2739
Iscrizione: mercoledì 16 gennaio 2013, 17:28
Desktop: ubuntu-2d
Distribuzione: Ubuntu 12.04.2 LTS i686
Località: Airuno(Lecco)

Re: Comunicazione tra processi in C usando due pipe

Messaggio da gila75 »

Difficile senza riscrivere da zero.
Comunque noto a occhio ( leggo da telefono e faccio fatica): in fgets metti 0 se trovi il carattere '/n'.
Ma in realta' il terminatote stringa è '\0'.
Non sarà li il problema, ma quello non va bene di sicuro
Scrivi risposta

Ritorna a “Programmazione”

Chi c’è in linea

Visualizzano questa sezione: 0 utenti iscritti e 7 ospiti