PDA

View Full Version : [C unix] pipe, read & write


stella_650
02-07-2008, 08:59
Ciao a tutti,
ho un problema riguardante la comunicazione tramite pipe relativo ad una somma di N righe di una matrice. Nel caso specifico creo la matrice 3*3, creo 3 processi ciascuno dei quali si occupa di calcolare la somma su ciascuna riga. Nel momento in cui uso la write sul descrittore di scrittura della pipe, mi rendo conto che non viene comunicato bene quel valore. La domanda è:

E' corretto passare un valore intero tramite le seguenti istruzioni?


int main(void)
{
int i,j,num,matrice[3][3],pfd1[2],pfd2[2],somma1i,somma2i,somma3i,somma1r,somma2r,somma3r,somma12i,somma23i,somma12r;
pid_t pid1,pid2,pid3;
for(i=0;i<3;i++)
{
for(j=0;j<3;j++)
{
num=rand()%11; //genera numeri casuali tra 0 e 10
matrice[i][j]=num;
printf("matrice [%d][%d] = %d\n",i,j,matrice[i][j]);
}
}
if((pid1=fork())<0)
{
printf("Errore fork!\n");
perror("fork");
}
if(pid1==0)
{
printf("FIGLIO 1 %d\n",getpid());
somma1i=0;
for(j=0;j<3;j++)
somma1i=somma1i+matrice[0][j];
printf("Somma1 = %d\n",somma1i);
close(pfd1[0]);
close(pfd2[0]);
close(pfd2[1]);
//scrivere sulla prima pipe la prima somma
write(pfd1[1],&somma1i,sizeof(somma1i));
close(pfd1[1]);
exit(0);
}

//secondo figlio.....
......
read(pfd1[0],&somma1r,1);
printf("FIGLIO 2 %d riceve somma1 %d\n",getpid(),somma1r);
.......



Questo è solo la prima parte relativa alla scrittura del primo valore calcolato sulla prima riga. ma già qui non funziona la ricezione del primo valore.
Cosa è che non va?
Grazie a priori.

DanieleC88
02-07-2008, 12:21
Dove lo fai il pipe()? :wtf:

stella_650
02-07-2008, 14:03
Dove lo fai il pipe()? :wtf:

Scusami, nella copia a pezzi ho dimenticato quella istruzione. Il problema è un po' particolare:
perchè se faccio la stampa di quello che leggo dalla pipe ottengo dei valori alti, come se fossero degli indirizzi fintanto che nn arrivo alla somma finale del terzo figlio che stampa correttamente il risultato.
Come è possibile?
Segue il codice (stavolta per intero :D):


#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
int main(void)
{
int i,j,num,matrice[3][3],pfd1[2],pfd2[2],somma1i,somma2i,somma3i,somma1r,somma2r,somma3r,somma12i,somma23i,somma12r;
pid_t pid1,pid2,pid3;
if(pipe(pfd1)==-1)
perror("pipe");
if(pipe(pfd2)==-1)
perror("pipe");
for(i=0;i<3;i++)
{
for(j=0;j<3;j++)
{

num=rand()%11; //genera numeri casuali tra 0 e 10
matrice[i][j]=num;
printf("matrice [%d][%d] = %d\n",i,j,matrice[i][j]);
}
}
if((pid1=fork())<0)
{
printf("Errore fork!\n");
perror("fork");
}
if(pid1==0)
{
printf("FIGLIO 1 %d\n",getpid());
somma1i=0;
for(j=0;j<3;j++)
somma1i=somma1i+matrice[0][j];
printf("Somma1 = %d\n",somma1i);
close(pfd1[0]);
close(pfd2[0]);
close(pfd2[1]);
//scrivere sulla prima pipe la prima somma
write(pfd1[1],&somma1i,1);
close(pfd1[1]);
exit(0);
}
if((pid2=fork())<0)
{
printf("Errore fork!\n");
perror("fork");
}
if(pid2==0)
{
printf("FIGLIO 2 %d\n",getpid());
somma2i=0;
for(j=0;j<3;j++)
somma2i=somma2i+matrice[1][j];
printf("Somma2 = %d\n",somma2i);

close(pfd1[1]);
close(pfd2[0]);
read(pfd1[0],&somma1r,1);
printf("Letto somma1r %d\n",somma1r);
close(pfd1[0]);
printf("FIGLIO 2 %d riceve %d\n",getpid(),somma1r);
somma12i=somma1r+somma2i;
printf("Somma2i %d\n",somma12i);
write(pfd2[1],&somma12i,1);
close(pfd2[1]);
exit(0);
}
if((pid3=fork())<0)
{
printf("Errore fork!\n");
perror("fork");
}
if(pid3==0)
{
printf("FIGLIO 3 %d\n",getpid());
somma3i=0;
for(j=0;j<3;j++)
somma3i=somma3i+matrice[2][j];
printf("Somma3 = %d\n",somma3i);
close(pfd1[0]);
close(pfd1[1]);
close(pfd2[1]);
read(pfd2[0],&somma12r,1);
printf("FIGLIO 3 %d riceve %d\n",getpid(),somma12r);
close(pfd2[0]);
somma23i=somma12r+somma3i;
printf("Risultato somma righe %d\n",somma23i);
exit(0);
}
close(pfd1[0]);
close(pfd1[1]);
close(pfd2[0]);
close(pfd2[1]);
wait(NULL);
wait(NULL);
wait(NULL);
exit(0);
}



OUTPUT:
----------------------------------------------------------------------------------
matrice [0][0] = 6
matrice [0][1] = 10
matrice [0][2] = 6
matrice [1][0] = 2
matrice [1][1] = 1
matrice [1][2] = 4
matrice [2][0] = 0
matrice [2][1] = 6
matrice [2][2] = 3
FIGLIO 1 12858
Somma1 = 22
FIGLIO 2 12859
Somma2 = 7
Letto somma1r 134519830 <---------------------------anomalia
FIGLIO 2 12859 riceve 134519830 <---------------------------anomalia
Somma2i 134519837 <---------------------------anomalia
FIGLIO 3 12860
Somma3 = 9
FIGLIO 3 12860 riceve 29
Risultato somma righe 38 <------------------------ora corretto???
-------------------------------------------------------------------------------------

Grazie...

DanieleC88
02-07-2008, 19:11
Effettivamente dà lo stesso problema anche a me... :( :boh:

Missionario86
17-07-2008, 15:41
Scusa il ritardo nella risposta, ma mi sono imbattuto solo adesso in questo topic.
Il problema sono le read e le write, anzi per essere preciso il terzo argomento delle read e delle write. Trattandosi di int il terzo argomento non deve essere "1"
come hai scritto tu nel codice, ma devi mettere sizeof(int). Così verrà rilevata automaticamente la lunghezza dell'intero da leggere o scrivere.
Ti faccio l'esempio
Tuo codice ---> write(pfd1[1],&somma1i,1);
Codice corretto ---> write(pfd1[1],&somma1i,sizeof(int));
Cambia le tue read e write in questo modo e vedrai che l'output sarà corretto.
Spero di essere stato utile.
Un saluto Missionario86:)