Visualizzazione dei risultati da 1 a 1 su 1
  1. #1
    Utente di HTML.it
    Registrato dal
    Sep 2017
    Messaggi
    0

    [C] Memoria condivisa: programma rimane in sospeso

    Salve, sono nuova del forum, spero di essere nella sezione giusta.


    Non riesco a far funzionare questo programma, o meglio, a volte funziona e mi crea i file corretti, a volte no. Ma in entrambi i casi nel terminale rimane in sospeso fino a quando non premo ctrl+c.


    Ecco la traccia:




    Scrivere un programma potenzeP che invocato dalla linea di comando scrivendo


    potenzeP nomefile M N


    genera M file


    nomefile.1 nomefile.2 ... nomefile.M


    tali che il file nomefile.i contenga le potenze i-esime degli interi memorizzati in nomefile. I file devono essere generati in parallelo utilizzando N processi figli mediante il meccanismo produttore/consumatore. Il processo padre deve svolgere il ruolo di unico produttore e i processi figli quello di consumatori. Il dato che il produttore deve fornire ai consumatori è semplicemente l'esponente i che deve essere usato dal consumatore per generare il file.


    Gli interi contenuti in nomefile devono essere memorizzati in un array condiviso creato con shmget() e chiave IPC_PRIVATE; lo stesso meccanismo deve essere usato per qualsiasi variabile condivisa utilizzata dal meccanismo produttore/consumatore.


    Come in tutti gli schemi produttore-consumatore è importante stabilire un meccanismo che permetta al produttore di segnalare ai consumatori che non ci sono altri valori da elaborare. La dimensione del buffer dei consumatori deve essere una costante, modificabile attraverso la compilazione




    Ecco il mio programma:

    codice:
    #define _GNU_SOURCE
    #include <semaphore.h>
    #include <stdio.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <stdbool.h>
    #include <assert.h>
    #include <stdlib.h>
    #include <sys/ipc.h>
    #include <sys/shm.h>
    #include <sys/wait.h>
    #include <math.h>
    #include <pthread.h>
    #define SIZE 10
    
    
    int main(int argc, char *argv[]){
        int err;
        if(argc != 4){//Faccio i controlli e assegno gli argomenti
            fprintf(stderr,"Non ci sono i 4 elementi richiesti!\n\n\tUso:\t %s nomeFile numeroFile numeroThread\n\n",argv[0]);
            exit(1);
        }
        if((argv[2] || argv[3]) < 0){
            fprintf(stderr,"Ho bisogno di numeri positivi!\n");
            exit(1);
        }
        int M = atoi(argv[2]);
        int N = atoi(argv[3]);
        char *nomeFile = argv[1];
    
    
        int *buffer;//dichiaro variabili
        int *interi;
        FILE *f = fopen(nomeFile, "r");
        int numero;
        int linee = 0;
        pid_t pid;
        int indiceC = 0;
        int *indiceP;
    
    
        int shmid1 = shmget(IPC_PRIVATE, SIZE*(sizeof(int)), 0600);//inizializzo buffer condiviso
        if(shmid1 == -1)puts("Errore nella creazione buffer condiviso!\n");
        buffer = shmat(shmid1, NULL, 0); 
        puts("Ho inizializzato il buffer condiviso\n");
    
    
        while(fscanf(f, "%d", &numero) != EOF){//conto numeri nel file
        linee+=1;
        }
        rewind(f);
    
    
        int shmid2 = shmget(IPC_PRIVATE, linee*(sizeof(int)), 0600);//inizializzo array di interi condiviso
        if(shmid2 == -1)puts("Errore nella creazione array di interi condiviso!\n");
        interi =  shmat(shmid2, NULL, 0); 
        puts("Ho inizializzato l'array di interi condiviso\n");
        
        int shempty = shmget(IPC_PRIVATE, sizeof(sem_t), 0600);//creo memoria per semafori
        if(shempty == -1)puts("Errore nella creazione semaforo empty condiviso!\n");
        int shfull = shmget(IPC_PRIVATE, sizeof(sem_t), 0600);
        if(shfull == -1)puts("Errore nella creazione semaforo full condiviso!\n");
        int shmutex = shmget(IPC_PRIVATE, sizeof(pthread_mutex_t), 0600);
        if(shmutex == -1)puts("Errore nella creazione mutex condiviso!\n");
        puts("Ho creato i semafori condivisi\n");
    
    
        sem_t *empty = (sem_t *) shmat(shempty, NULL, 0);//associo i semafori
        sem_t *full = (sem_t *) shmat(shfull, NULL, 0); 
        pthread_mutex_t *mutex = (pthread_mutex_t *) shmat(shmutex, NULL, 0);
        puts("Ho associato i semafori\n");
    
    
         err = sem_init(empty, 1, SIZE);
         assert(err == 0);
         err = sem_init(full, 1, 0);
         assert(err == 0);
         err = pthread_mutex_init(mutex,NULL);
         assert(err == 0);
        int shIndiceP = shmget(IPC_PRIVATE, sizeof(int), 0600);//creo indice produttore condiviso
        if(shIndiceP == -1)puts("Errore nella creazione indice produttore condiviso!\n");
        indiceP = (int *) shmat(shIndiceP, NULL, 0);
        *indiceP = 0;
        puts("Ho creato e associato l'indice del produttore condiviso");
    
    
        for(int i = 0; i < linee; i++){//creo array di interi del file
        fscanf(f, "%d", &numero);
        interi[i] = numero;
        }
        fclose(f);
    
    
        for(int i = 0; i < N; i++){
        pid = fork();printf("FIGLIO: creato processo %d\n",i);
        if(pid == -1){
            perror("Errore nella fork!\n");
            exit(1);
        }
            if(pid == 0){  printf("FIGLIO: entro nel processo %d\n",i);
            while(1){
                err = sem_wait(full);
                assert(err == 0);printf("Entro nel processo %d\n",i);
                err = pthread_mutex_lock(mutex);
                assert(err == 0);    
            
                int n = buffer[(*indiceP)++ % SIZE];printf("FIGLIO: Ho prelevato il numero %d e sono %d\n",n,i);
                
                if(n == 0){
                    err = pthread_mutex_unlock(mutex);
                    assert(err == 0);            
                    err = sem_post(empty);
                    assert(err == 0);
                    exit(0);
                }
                err = pthread_mutex_unlock(mutex);
                assert(err == 0);            
                err = sem_post(empty);
                assert(err == 0);
    
    
                char potenze[25];
                snprintf(potenze, 25, "%s.%d", nomeFile, n);
                FILE *fpot = fopen(potenze,"w");
                if(fpot == NULL)fprintf(stderr,"Errore creazione file\n");
                for(int i = 0; i < linee; i++){
                    fprintf(fpot, "%ld\n", (long)(pow(interi[i],n)));
                }
                fclose(fpot);
            }
              }
        }   
    
    
        for(int i = 1; i <= M; i++){//procedura produttore (padre)
            err = sem_wait(empty);
            assert(err == 0);
            err = pthread_mutex_lock(mutex);
            assert(err == 0);
            buffer[indiceC++ % SIZE] = i;printf("PADRE: ho scritto %d sul buffer\n",i);
            err = pthread_mutex_unlock(mutex);
            assert(err == 0);            
            err = sem_post(full);
            assert(err == 0);
        }
        for(int i = 0; i < N; i++){
            err = sem_wait(empty);//inserisco carattere di fine
            assert(err == 0);
        err = pthread_mutex_lock(mutex);
        assert(err == 0);
            buffer[indiceC++ % SIZE] = 0;printf("PADRE: ho scritto %d sul buffer\n",0);
        err = pthread_mutex_unlock(mutex);
        assert(err == 0);                
        err = sem_post(full);
            assert(err == 0);
        }
       
        
        err = sem_destroy(empty);//pulisco semafori
        assert(err == 0);
        err = sem_destroy(full);
        assert(err == 0);
        err = pthread_mutex_destroy(mutex);
        assert(err == 0);
    
    
        shmctl(shmid1, IPC_RMID, NULL);//pulisco memoria condivisa
        shmctl(shmid2, IPC_RMID, NULL);
        shmctl(shempty, IPC_RMID, NULL);
        shmctl(shfull, IPC_RMID, NULL);
        shmctl(shmutex, IPC_RMID, NULL);
        shmctl(shIndiceP, IPC_RMID, NULL);
    
    
        return 0;
    }


    Non sono sicura se mandare il carattere di terminazione N volte o solo una, ma in entrambi i casi non funziona.
    Grazie mille a chi mi aiuterà
    Ultima modifica di LeleFT; 06-09-2017 a 12:42 Motivo: Aggiunti i tag CODE

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.