Problema con programma C con pipe

di il
2 risposte

Problema con programma C con pipe

Ho un problema con un programma C che deve ricevere da imput il nome di un file e N caratteri,il programma dovrebbe scandire linea per linea il file riportando in output una cosa del tipo
Il programma genera N programmi figli (con 1 fork) che devono gestire ognuno un carattere in maniera sincronizzata.

Linea1 occorrenze carattere a = tot occorrenze carattere b = tot ...
Linea2 occorrenze carattere a = tot occorrenze carattere b = tot ...

ogni carattere deve essere controllato da un figlio diverso.
Per ora la mia versione del programma e' quella che riporto sotto..
come problema ha che non e' sincronizzata (in output da tutte le occorrenze di tutti i caratteri per tutti i figli e solo dopo che hanno terminato tutti da le linee scandite dal padre)
Non capisco perche' non si sincronizzano.. se qualcuno potesse darmi una mano gli sarei molto grato



#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <signal.h>


typedef int pipe_t[2]; /* tipo che definisce una pipe */


main(int argc,char *argv[])
{
int pid, ncaratteri, lettura, scrittura, fdr, linee, max;
int i, k,padre[2], j, z, n;
char ok, ch, cmax;
struct {
int conteggio; /* numero di occorrenze attuali del carattere */
char c; /* carattere letto */
} msg;

pipe_t *p; /* array dinamico di pipe */

linee = atoi(argv[2]);
max=0;
cmax=' ';
/* Controllo sul numero dei parametri */
if (argc<4)
{
printf ("Errore nel numero di parametri \n");
exit(1);
}

/* Numero di caratteri passati sulla linea di comando */

ncaratteri=argc-3;

/* Allocazione dell'array di pipe */

if ((p=malloc(ncaratteri*sizeof(pipe_t)))==0)
{
printf("Errore nella malloc\n");
exit(1);
}

for (i=0; i<ncaratteri; i++)
{
if(pipe(p[i])<0)
{
printf("errore nella creazione della pipe \n");
exit(1);
}
}

/* Creazione della pipe di comunicazione col padre per l'ultima riga*/

if(pipe(padre)<0)
{
printf("errore nella creazione della pipe \n");
exit(1);
}

for (i=1; i<=ncaratteri; i++) /* for di creazione dei figli */
{
/*creazione dei figli*/
if((pid=fork())<0)
{
printf ("errore nella fork");
exit(1);
}


if(pid==0) /* figlio */
{
msg.c=argv[i+2][0];
printf(" \n Figlio %d con pid %d\n", i, getpid());
/* pipe da cui leggere l'ok */
lettura = i-1;
/* pipe su cui scrivere l'ok */
scrittura = i;

/* chiude tutte le pipe non usate */
for(z=0; z<ncaratteri; z++)
{
if (z!=scrittura)
close(p[z][1]);
if (z!=lettura)
close(p[z][0]);
}

close(padre[0]);
/*apre il file*/
if((fdr=open(argv[1],O_RDONLY))<0)
{
printf("errore nell'apertura del file %s",argv[1]);
exit(1);
}
msg.conteggio=0; /* per contare il numero dei caratteri della riga */
k=1; /* per numerare le righe */
/* legge il file carattere per carattere */
while((read(fdr,&ch,1)>0)&&(k!=linee+1))
{
if(ch=='\n') /* E.O.L. */
{
read(p[lettura][0], &ok, 1);
printf (", %d occorrenze del carattere %c \n", msg.conteggio, msg.c);

if(k==linee) /°se e' l'ultima riga passa msg al padre per l'elaborazione dei dati
write(padre[1].&msg,1);

/* da l'ok al prossimo figlio */
write (p[scrittura], &ok, 1);

/* riga successiva */
k++;
msg.conteggio=0;
}
else
{
if(msg.c==ch)
{
msg.conteggio++;
}
}
} /* while per la scansione dei caratteri

/* Si prepara all'ultimo passaggio */
/* da l'ok al prossimo figlio */
write (p[scrittura], &ok, 1);
/* esce */
exit(0);
} /* if - figlio */
} /* for - ciclo di creazione dei figli */

/* padre */

printf (" \n Padre con pid %d \n",getpid() );

k=0;

/* chiude tutte le pipe non usate */
for (z=0; z<ncaratteri; z++)
{
if (z != 0)
close(p[z][1]);

if (z != ncaratteri)
close(p[z][0]);
}

close(padre[1]);

/* Si sincronizza con i figli per ottenere l'output richiesto */
for (k=1; k<=linee; k++)
{
/* Stampa l'intestazione della linea */
printf ("\n Linea %d: ", k);

/* da l'ok al primo processo*/
write(p[0][1], &ok, 1);

/* si mette in attesa dell'ultimo figlio */
read(p[ncaratteri][0], &ok, 1);
/* Stampa l'intestazione della linea */
printf ("\n Linea %d: ", k);
}

/* Al termine della stampa di tutte le righe, il padre deve effettuare la stati
stica */


for (i=1; i<=ncaratteri; i++)
{
read(padre[0], &msg, sizeof(msg));
if (max<msg.conteggio)
{
max=msg.conteggio;
cmax=msg.c;
}
}

/* Stampa la statistica e termina */
printf("\nIl carattere apparso piu volte e %c apparso %d volte", cmax, max);

exit(0);

} /* fine del main */

2 Risposte

  • Re: Problema con programma C con pipe

    Ciao,
    purtroppo non so aiutarti ma forse tu potresti aiutare me visto che stai lavorando anche tu con la pipe.Il mio messaggio è quello sulla comunicazione in Unix,cmq lo riscrivo di seguito:

    Devo realizzare due programmi, Gestore e Clienti, che comunicano in Unix(in locale).I Clienti sono n e devono inviare ad un unico Gestore il loro pid e due pathname.Per far ciò ho utilizzato una pipe con nome(FIFO) sul quale viene inviata, da ogni Cliente, un messaggio contenente pid e pathname.Vorrei sapere se la soluzione va bene, o devo utilizzare una struct(vorrei evitare!!!)
    grazie
  • Re: Problema con programma C con pipe

    Allora , io ti so rispondere per quanto riguarda il C , in unix non credo si possano fare pipe se non quelle teoriche tipo ">" o ">>".
    In c se un processo deve scrivere su di una pipe puo' passare con 1 write solo 1 dato alla volta e deve essere del tipo
    write(pipe[i][1],&nomedato,sizeof(dato));
    percio' se vuoi passare due dati distinti le possibilita' sono due
    o fai 1 struct con due valori dentro
    o semplicemente fai 2 write (e nel processo che aspetta i dati ci dovranno essere 2read*numerodeiprocessifigli
Devi accedere o registrarti per scrivere nel forum
2 risposte