PDA

Visualizza la versione completa : Esercizio su matrici con IPC e processi concorrenti


thorberg
26-06-2017, 14:05
Ciao a tutti ragazzi/e, sono alle prime armi con c e nuovo nel forum, e sicuramente nell'esercizio che segue avrò fatto molti errori perché quando mando in esecuzione il compilatore non da nessun errore ma non svolge nulla(con il file makefile va tutto bene, il problema è nel codice). Allego il testo dell'esercizio.

questo è il mio codice



#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <math.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include <sys/msg.h>

#define MSGKEY 88 //chiave per la coda dei messaggi del processo padre
#define MSGTYPE 1 //tipo per messaggio da ricevere
#define SEMKEY 89
int semid; //identificatore dell'array di semafori
int msgid; //identificatore della coda dei messaggi del processo padre

struct operation{
char type;
int i;
int j;
};

struct Processo{
int n_processo;
pid_t my_pid;
};

void mywrite(char *string);

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

if(argc != 6){
mywrite("ERRORE: Corretta esecuzione: ./ipc.x matA.txt matB.txt matC.txt <ordine-mat> <num-processi>\n");
exit(1);
}
int N = atoi(argv[4]);
int numP = atoi(argv[5]); //numero processi
int fdA, fdB, fdC;
//indici per i cicli
int i, j, k, w;

if((fdA = open(argv[1], O_RDONLY, 644)) == -1){
mywrite("ERRORE apertura argv[1]\n");
exit(1);
}

if((fdB = open(argv[2], O_RDONLY, 644)) == -1){
mywrite("ERRORE apertura argv[2]\n");
exit(1);
}

if((fdC = open(argv[3], O_RDWR, 666)) == -1){
mywrite("ERRORE apertura argv[3]\n");
exit(1);
}


//da qua provo soluzione bomber

char *test;
char testo[N];
int dimensione=1000; //grandezza arbitraria abbastanza grande
read(fdA, testo, dimensione);
int num;
test = strtok (testo,"\n");

int **matA = (int**) malloc(N * sizeof(int*));
for(i=0; i<N; i++){
matA[i] = (int*)malloc(N * sizeof(int));
}

for(i=0; i<N; i++){
for(j=0; j<N; j++){
num=atoi(test); // converto da ascii a numero intero
matA[i][j] = num;
test= strtok (NULL,"\n");
}
}

key_t keyA=123;
int id_mA;
if ((id_mA = shmget(keyA,sizeof(matA) , IPC_CREAT|0666)) == -1) {
mywrite("Errore memoria condivisa matA");
shmctl(id_mA, IPC_RMID, NULL);
exit(1);
}
matA=shmat(id_mA, NULL, 0);

char testoB[N];
int dimensioneB=1000; //grandezza arbitraria abbastanza grande
read(fdB, testoB, dimensioneB);
test = strtok (testoB,"\n");

int **matB = (int**) malloc(N * sizeof(int*));
for(i=0; i<N; i++){
matB[i] = (int*)malloc(N * sizeof(int));
}

for(i=0; i<N; i++){
for(j=0; j<N; j++){
num=atoi(test); // converto da ascii a numero intero
matB[i][j] = num;
test= strtok (NULL,"\n");
}
}

key_t keyB=456;
int id_mB;
if ((id_mB = shmget(keyB,sizeof(matB) , IPC_CREAT|0666)) == -1) {
mywrite("Errore memoria condivisa matB");
shmctl(id_mB, IPC_RMID, NULL);
exit(1);
}
matB=shmat(id_mB, NULL, 0);

int **matC = (int**) malloc(N * sizeof(int*));
for(i=0; i<N; i++){
matC[i] = (int*)malloc(N * sizeof(int));
}

for(i=0; i<N; i++){
for(j=0; j<N; j++){
matC[i][j] = 0;
}
}

key_t keyC=789;
int id_mC;
if ((id_mC = shmget(keyC,sizeof(matC) , IPC_CREAT|0666)) == -1) {
mywrite("Errore memoria condivisa matC");
shmctl(id_mC, IPC_RMID, NULL);
exit(1);
}
matC=shmat(id_mC, NULL, 0);

//risultato somma elementi di C
int *somma=(int*) malloc(sizeof(int*));
key_t keyN=111;
int id_N;
if ((id_N = shmget(keyN,sizeof(int),IPC_CREAT|0666)) == -1) {
mywrite("Errore memoria condivisa somma");
shmctl(id_N, IPC_RMID, NULL);
exit(1);
}
somma= shmat(id_N, NULL, 0);

struct sembuf * sops = (struct sembuf *) malloc (2*sizeof(struct sembuf));
//Creazione di un array di numP semafori
//Il semaforo 0 sincronizza il processo 1, sem 1 sincronizza processo 2 e cosi via..
key_t keysem=ftok(".", 'a');

if((semid = semget(SEMKEY, numP ,0666|IPC_EXCL|IPC_CREAT)) == -1){
mywrite("ERRORE creazione array di semafori");
semctl(semid, 0, IPC_RMID, 0);
exit(1);
}

//inizializzo i semafori e li metto in attesa
for(i=0; i<numP ; i++){
sops[0].sem_num = i;
sops[0].sem_op = 1; //attende che valga 0 per avere il via libera
sops[0].sem_flg = 0;
semop(semid, sops, 1);
}

//array di strutture che mi andrà a collegare ogni processo col proprio pid
struct Processo processi[numP];
int fdFtoC[2];
pipe(fdFtoC);
pid_t pid_padre=getpid();


if((msgid = msgget(MSGKEY, (0666|IPC_CREAT|IPC_EXCL))) == -1) {
mywrite("Creazione della coda di messaggi fallita");
exit(1);
}

//creo i processi e li salvo nell'array processi
int num_processo;
pid_t pid;

for(num_processo=0; num_processo<numP; num_processo++){

pid=fork();
if (pid == -1){
mywrite("ERRORE fork");
exit(1);
}
else if (pid == 0){ //figlio i

close(fdFtoC[1]); //chiudo l'output, il figlio legge e basta
processi[num_processo].n_processo= num_processo;
processi[num_processo].my_pid=getpid();

struct Processo mex= { num_processo, processi[num_processo].my_pid};
if(msgsnd(msgid, &mex, sizeof(struct Processo), 0) == -1){ //Sono stato creato, sono libero
mywrite("ERRORE invio messaggio al padre");
exit(1);
}



}else{ //padre
close(fdFtoC[0]); //chiudo l'input, il padre scrive e basta
}



}

int continuo=1;

while(continuo){

if(getpid()==pid_padre){ //codice del padre

for(i=0;i<N;i++){
for(j=0; j<N ;j++){
struct Processo *mex;
mex = (struct Processo *) malloc(sizeof(struct Processo));
if(msgrcv(msgid, mex, sizeof(struct Processo), MSGTYPE, 0) == -1){
mywrite("ERRORE ricezione messaggio dalla coda");
exit(1);
}
struct operation next; next.i=i; next.j=j; next.type='M';

sops[0].sem_num = mex->n_processo;
sops[0].sem_op = -1; //sblocco il semaforo a cui mando l'operazione
sops[0].sem_flg = 0;
semop(semid, sops, 1);

//padre scrive su pipe al figlio la prossima operazione
if(write(fdFtoC[1], &next, sizeof(struct operation)) == -1){
mywrite("ERRORE scrittura su pipe");
exit(1);
}
free(mex);
}
struct Processo *mex;
mex = (struct Processo *) malloc(sizeof(struct Processo));
if(msgrcv(msgid, mex, sizeof(struct Processo), MSGTYPE, 0) == -1){
mywrite("ERRORE ricezione messaggio dalla coda");
exit(1);
}
struct operation next; next.i=i; next.type='S';

sops[0].sem_num = mex->n_processo;
sops[0].sem_op = -1; //sblocco il semaforo a cui mando l'operazione
sops[0].sem_flg = 0;
semop(semid, sops, 1);

if(write(fdFtoC[1], &next, sizeof(struct operation)) == -1){
mywrite("ERRORE scrittura su pipe");
exit(1);
}

free(mex);

}

}else{ //codice figlio

for(i=0; i<numP ; i++){

if(getpid()==processi[i].my_pid){

sops[0].sem_num = i; //Semaforo numero i
sops[0].sem_op = 0; //attende che il semaforo valga zero
sops[0].sem_flg = 0;

sops[1].sem_num = i; //semaforo i
sops[1].sem_op = 1; //acquisisce la risorsa
sops[1].sem_flg = 0;

semop(semid, sops, 2);

char temp[100];
sprintf(temp, "Processo: %d\t\tpid:%d\n\t\tHo acquisito la risorsa, svolgo l'operazione\n\n", i+1, processi[i].my_pid);
mywrite(temp);

//figlio legge da pipe l'operazione che dovrà svolgere
struct operation *next;
next = (struct operation *) malloc(sizeof(struct operation));
if(read(fdFtoC[0], &next, sizeof(struct operation)) == -1){
mywrite("ERRORE lettura da pipe");
exit(1);
}
if(next->type=='M')
for(k=0 ; k<N ; k++)
matC[next->i][next->j] += matA[next->i][k] * matB[k][next->j];

if(next->type=='S')
for(w=0; w<N ; w++)
somma+=matC[next->i][w];

sprintf(temp, "Processo: %d\t\tpid:%d\n\t\tHo svolto l'operazione, lo comunico al padre\n\n", i+1, processi[i].my_pid);
mywrite(temp);

struct Processo mex= { i, processi[i].my_pid};
if(msgsnd(msgid, &mex, sizeof(struct Processo), 0) == -1){ //ho svolto l'operazione
mywrite("ERRORE invio messaggio al padre");
exit(1);
}
free(next);
}
}
}
continuo=0;
}

//stampo la matrice C su file
char porzione[32];
for (i = 0 ; i < N ; i++){
for (j = 0 ; j < N ; j++){
lseek(fdC, 0, SEEK_END);
sprintf(porzione, "%d\t", matC[i][j]);
write(fdC, porzione, sizeof(porzione));
}
lseek(fdC, 0, SEEK_END);
sprintf(porzione, "\n");
write(fdC, porzione, sizeof(porzione));
}

sprintf(porzione, "La somma degli elementi della matrice C é: %d\n", *somma);
mywrite(porzione);

for(i=0; i<N; i++){
free(matA[i]);
}
free(matA);

for(i=0; i<N; i++){
free(matC[i]);
}
free(matC);

for(i=0; i<N; i++){
free(matC[i]);
}
free(matC);

shmctl(id_N, IPC_RMID, NULL);
free(somma);

//rimuovo i semafori
semctl(semid, 0, IPC_RMID, 0);
//rimuovo la coda di messaggi
msgctl(msgid, IPC_RMID, NULL);

shmctl(id_mA, IPC_RMID, NULL);
shmctl(id_mB, IPC_RMID, NULL);
shmctl(id_mC, IPC_RMID, NULL);


}

void mywrite(char *string){
write(1, string, strlen(string));
}

Loading