Visualizzazione dei risultati da 1 a 1 su 1
  1. #1

    Esercizio su matrici con IPC e processi concorrenti

    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

    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));
    }
    File allegati File allegati
    Ultima modifica di LeleFT; 26-06-2017 a 14:20 Motivo: Aggiunti i tag CODE

Tag per questa discussione

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.