Παιδιά για μια εργασία έχω κάνει τα εξής αρχεία:
Test1.c Περιέχει την main:
- Κώδικας: Επιλογή όλων
#include <stdio.h>
#include "pipe.h"
/*
This code multiplicates 2 2d arrays using multiple processes simulating a distubuted way of array multiplication by using pipes
*/
int main(int argc,char **argv)
{
int ***data;//Here we store the data
int i,j,k,status;//i,j,k variables usefull for loops
//status we need in order to check the if each child has exit with error or not
/*
*row stores the matrix fo the current row
**col trores the current column ans the answer that child sends to the father and
**result the final matrix.
*/
int *row,**col,**result,*ans,*temp;
/*
here we store the dimentions of each table that takes place into multiplication.
data1_d: stores the first matrix dimantions
data2_d: Stores the second matrix dimantions
datae_d: Stores Data for final Matrix
*/
dimensions data1_d,data2_d,data3_d;
pipe_s *p;//Here we set up the pipes and we store the pids for
pid_t pid;
const char *path = "matrix.txt";//The path we load the file
data = (int ***)load(path,&data1_d,&data2_d);//reading matrices
result=(int **)piliko(data1_d,data2_d,&data3_d);//allocating final result table
p=calloc(data1_d.height,sizeof(pipe_s));//allocating secial struct for pipes anf storing the pid of fork
if(result==NULL && p==NULL && data==NULL)//cannot allocate space for result
{
fprintf(stderr,"Cannot alocate final result table\n");
exit(EXIT_FAILURE);
}
for(i=0;i<data1_d.height;i++)//MAking Child processes
{
if(pipe(p[i].from_father)<0 && pipe(p[i].from_child)<0 )
{
fprintf(stderr,"Error with pipes.\n");
exit(EXIT_FAILURE);
}
p[i].pid=fork();
if(p[i].pid>0)//Father
{
/*Sending Line*/
if(write(p[i].from_father[1],data[0][i],data1_d.length*sizeof(int))!=(data1_d.length*sizeof(int)))
{
fprintf(stderr,"Cannot write data\n");
exit(EXIT_FAILURE);
}
/*Sending Columns*/
for(j=0;j<data2_d.length;j++)
{
temp=column((int **)data[1],j,data2_d.height);
if(temp==NULL)
{
exit(EXIT_FAILURE);
}
printf("Send into pipe column %d\n",j);
if(
write(p[i].from_father[1],(void *)temp,data2_d.height*sizeof(int))!=data2_d.height*sizeof(int)
)
{
fprintf(stderr,"Cannot send columns\n");//error
exit(EXIT_FAILURE);
}
else
{
printf("%d has Sent \n",i);
}
free(temp);
}
}
else if(p[i].pid==0)
{
fflush(stdout);
/*Alocating Spaces*/
row=calloc(data1_d.length,sizeof(int));//for rows
ans=calloc(data3_d.length,sizeof(int));//for answer
col=calloc(data2_d.length,sizeof(int *));//for columns
/*If cannot alocate at least on of them*/
if(row==NULL && col==NULL && ans==NULL)
{
fprintf(stderr,"Cannot allocate space for the required Matrices\n");
exit(EXIT_FAILURE);
}
/*Allocate space for receiving column matrix*/
for(j=0;j<data2_d.length;j++)
{
col[j]=calloc(data2_d.height,sizeof(int));
if(col[j]==NULL)
{
fprintf(stderr,"Cannot allocate space for the required Matrices\n");
exit(EXIT_FAILURE);
}
}
/*Reading a line if not then it shows the apropriate message and exits*/
if(read(p[i].from_father[0],row,data1_d.length*sizeof(int))<=0)
{
fprintf(stderr,"No data read\n");
exit(EXIT_FAILURE);
}
/*Reading Columns*/
for(j=0;j<data2_d.length;j++)
{
if(read(p[i].from_father[0],(void *)col[j],data2_d.height*sizeof(int))<data2_d.height*sizeof(int))
{
fprintf(stderr,"No data read i=%d j=%d\n",i,j);
exit(EXIT_FAILURE);
}
}
/*Calculating row*/
for(k=0;k<data3_d.length;k++)
{
ans[i]=iMatxmult(row,col[k],data1_d.length,NULL);
}
/*Sending final result*/
if(write(p[i].from_child[1],ans,data3_d.length*sizeof(int))<(data3_d.length*sizeof(int)))
{
fprintf(stderr,"Cannot send final result\nBye\n");
exit(EXIT_FAILURE);
}
exit(EXIT_SUCCESS);
}
else if(p[i].pid<0)
{
fprintf(stderr,"Fork failed");
exit(EXIT_FAILURE);
}
}
k=0;
while(k<data1_d.height)
{
pid=wait(NULL);
for(j=0;j<data3_d.height;j++)
{
if(pid==p[j].pid)
{
/*Reading result*/
if(read(p[j].from_child[0],result[j],data3_d.length*sizeof(int))<=0)
{
fprintf(stderr,"Cannot fetch final table\n");
exit(EXIT_FAILURE);
}
else
{
printf("Child sucessfully read data\n");
}
k++;
pid=0;
}
}
}
/*Printing results*/
puts("Printing Final result\n");
printIntMatrix(result,data3_d.height,data3_d.length);
return 0;
}
pipe.h: περιέχει μια χρήσιμη δομή για το test1.c
- Κώδικας: Επιλογή όλων
#ifndef PIPEH
#define PIPEH
#include<sys/types.h>
#include<unistd.h>
#include<stdlib.h>
#include"MaxMul.h"
#include"header.h"
/*With this struct I bring all together the pids and the pipes*/
typedef struct
{
pid_t pid;//PID using for fork() function
int from_father[2];//Pipe that father sends data to child from father[0]X is the data and from father[1][X] is control
int **from_father_col;//pipe that I use to send columns
int from_child[2];//Pipe that sends the child to the father
}pipe_s;
#endif
MaxMul.h : Έχει χρήσιμες συναρτήσεις για να υπολογίζει τον τελικό πίνακα του γινομένου και να τυπώνει έναν δισδιάστατο πίνακα
- Κώδικας: Επιλογή όλων
#ifndef MAXMUL_
#define MAXMUL_
#include<stdlib.h>
#include<stdio.h>
typedef struct{
unsigned int height;//Pli8os grammwn
unsigned int length;//Pli8os Stilwn
}dimensions;
/*Epistrefei enan pinaka me tis times tis col stilit tou pinaka matrix*/
int * column(int **matrix,int col,int height);
/*Ektelei ton pollaplasiasmo tis row grammis kai tis col stilis*/
int iMatxmult(int row[], int col[],unsigned int size,int * result);
/*Kataskeuazei ton teliko pinaka kai epistrefei to mege8ow tou telikou pinaka elegxontas an ginetaqi o pollaplasiasmos twn pinakwn*/
int **piliko(dimensions a,dimensions b,dimensions *result);
/*Typwnei enan height*length disdiastato pinaka*/
void printIntMatrix(int **matrix,int height,int length);
#endif
MaxMul.c Οι υλοποίηση των συναρτήσεων του MaxMul.h
- Κώδικας: Επιλογή όλων
#include "MaxMul.h"
int * column(int **matrix,int col, int height)
{
int *colymn=calloc(height,sizeof(int)),i;
if(colymn!=NULL)
{
for(i=0;i<height&&matrix[i]!=NULL;i++)
{
colymn[i]=matrix[i][col];
}
}
return colymn;
}
int iMatxmult(int row[], int col[],unsigned int size,int * result)
{
int i;
int mult=0;
if(row!=NULL && col!=NULL)
{
for(i=0;(unsigned)i<size;i++)
{
mult+=row[i]*col[i];
}
return mult;
}
}
int **piliko(dimensions a,dimensions b,dimensions *result)
{
int **res,i;
if(a.length!=b.height)
{
return NULL;
}
result->height=a.height;
result->length=b.length;
res=calloc(result->height,sizeof(int *));
for(i=0;(unsigned)i<result->height;i++)
{
res[i]=calloc(result->length,sizeof(int));
}
return res;
}
void printIntMatrix(int **matrix,int length,int height)
{
int i,j;
for(i=0;i<length;i++)
{
for(j=0; j<height ; j++)
{
printf("%d\t",matrix[i][j]);
}
putchar('\n');
}
}
header.h Το Header με την δήλωση της συνάρτησης όπου χρησιμοποιεί το newload.c
- Κώδικας: Επιλογή όλων
#ifndef HEADER
#define HEADER
#include<stdlib.h>
#include<stdio.h>
#include "MaxMul.h"
int ***load(const char *path,dimensions *data1_d,dimensions *data2_d);
#endif
newload.c Φορτώνει 2 δισδιάστατους πίνακες από το αρχείο
- Κώδικας: Επιλογή όλων
#include <stdio.h>
#include <stdlib.h>
#include "header.h"
#include "MaxMul.h"
int ***load(const char *s,dimensions *data1_d,dimensions *data2_d){
FILE *fp = fopen(s,"r");/*Oppening a file*/
/*i,j variavble for traversing 2d array*/
int i,j;
/*
A= we neeed it to make a matrix of 2d arrays
buffer = temporary storage buffer of 2d arrays
*/
int ***A=NULL,**buffer=NULL;
fscanf(fp,"%d %d",&data1_d->height,&data1_d->length); //reading Dimentions from file
A=(int ***)malloc(2*sizeof(int **)); //Allocating 2 2d arrays
buffer = (int**)malloc(sizeof(int*)*data1_d->height); //Allocating temporary storage
if(A!=NULL)
{
A[0] = (int**)malloc(sizeof(int*)*data1_d->height);//Allocating first array
}
if(A[0]==NULL)
{
return NULL;
}
/*More allocation of the array*/
for(i=0;i<data1_d->height && A[0] !=NULL ;i++)
{
buffer[i] = (int*)malloc(sizeof(int)*data1_d->length);
A[0][i] = (int*)malloc(sizeof(int)*data1_d->length);
if(buffer[i]==NULL && A[0][i]==NULL)
{
fprintf(stderr,"error with pipes\n");
return NULL;
}
}
/*Filling the 2d array with data from the file*/
for(i=0;i<data1_d->height;i++)
{
for(j=0;j<data1_d->length;j++)
{
fscanf(fp,"%d",&buffer[i][j]);
A[0][i][j] = buffer[i][j];
}
}
free(buffer); //free buffer
fscanf(fp,"%d %d",&data2_d->height,&data2_d->length); //reading dimention for the second array
buffer = (int**)malloc(sizeof(int*)*data2_d->height); //reallocating buffer
A[1] = (int**)malloc(sizeof(int*)*data2_d->height);//Allocating the second matrix
if(buffer==NULL && A[1]==NULL)
{
fprintf(stderr,"error with pipes\n");
return NULL;
}
for(i=0;i<data2_d->height;i++)
{
buffer[i] = (int*)malloc(sizeof(int)*data2_d->length); //Desmeush 8esewn sth mnhmh
A[1][i] = (int*)malloc(sizeof(int)*data2_d->length); //Desmeush 8esewn sth mnhmh
}
/*Filling second matrix*/
for(i=0;i<data2_d->height;i++)
{
for(j=0;j<data2_d->length;j++)
{
fscanf(fp,"%d",&buffer[i][j]);
A[1][i][j] = buffer[i][j];
}
}
/*Prepating for end*/
free(buffer);
fclose(fp);
return A;//return final Matrix
}
Τα δεδομένα τα παίρνει από το αρχείο:
Αυτό όπου κάνει εν ολίγοις το πρόγραμμα είναι να παίρνει 2 πίνακες και να τους Πολλαπλασιάζει με κατανεμημένο τρόπο χρησιμοποιώντας διεργασίες παιδιά και pipes. Κάθε διεργασία παιδί υπολογίζει μια γραμμή του τελικού πίνακα του γινομένου.Αλλά το πρόβλημα είναι ότι το τελικό αποτέλεσμα είναι σωστό και τα παιδιά υπολογίζουν σωστά την εκάστοτε γραμμή αλλά η διεργασία πατέρας δεν παίρνει τα σωστά δεδομένα.... Γιατί?
ΔΕΝ ΑΝΤΕΧΩ ΑΛΛΟ