emp3hack icon

esame-01-09-14

emp3hack | PRO | 12/27/15 09:40:10 AM UTC | 0 ⭐ | 11728 👁️ | Never ⏰ | []
C for Macs |

0 B

|

None

|

0 👍

/

0 👎

/* Esame del 01/09/14
 * 
 * In una applicazione concorrente k threads condividono r risorse equivalenti dovendo eseguire ognuna una diversa
 * elaborazione che necessita di una istanza delle risorse.
 *
 * Scrivere un programma C che generi ad intervalli casuali i thread di calcolo che non dovranno mai essere piu` di k
 * Ogni thread richiede tramite la funzione Richiesta() l’accesso ad una istanza libera delle r risorse, se ce ne sono.
 * La funzione assegna la risorsa e torna un indice della stessa sotto forma di intero compreso tra 0 e r − 1;
 * La funzione ritorna sempre un valore, aspettando che una risorsa si liberi se non ci sono istanze disponibili.
 *
 * Il generico thread esegue la computazione invocando una funzione il cui prototipo `e void Elabora( int x ),
 * essendo x la risorsa assegnata al thread.
 * Dopo aver fatto uso della istanza della risorsa il thread la rilascia invocando una funzione il cui prototipo
 * e' void Rilascia( int x ), dove x indica l’indice della risorsa da rendere disponibile.
 * Specificare la stuttura del generico thread e le funzioni Richiesta() e Rilascia() in modo tale che
 * ogni istanza di risorsa venga usata da non piu’ di un thread alla volta anche se piu` thread eseguono in modo
 * concorrente.
 * 
 * Svolgimento a cura di Emanuele Munafò. 
 * Pertanto la soluzione data potrebbe essere inesatta e/o errata.
 */
 
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>
 
#define K 10
#define R 4
 
sem_t s_nrisorselibere; // Contatore del numero delle risorse libere
pthread_mutex_t m_BMrisorsacondivisa; // Mutex per proteggere la bitmap della risorsa condivisa
short int BMrisorsacondivisa[R]; // Bitmap risorsa condivisa 0: risorsa libera, 1: risorsa occupata
sem_t s_maxthreads;
 
// Prototipi funzioni
unsigned int richiesta();
void rilascia(int x);
void* runner(void* runner);
void* elabora(int x);
 
int main(int argc, char const *argv[]){
    int r;
    pthread_t pid;
    // Inizializzo mutex e semafori
    sem_init(&s_nrisorselibere, 0, R); // Inizialmente tutte le risorse sono libere
    sem_init(&s_maxthreads, 0, K);
    pthread_mutex_init(&m_BMrisorsacondivisa, NULL);
    // Inizializzo la bitmap a 0
    for(int i=0;i<R;++i){
        BMrisorsacondivisa[i] = 0;
    }
    // Inizializzo seme random
    srand(time(NULL));
 
    // Genero sempre thread ma max K
    while(1){
        sem_wait(&s_maxthreads);
        r = rand()%300;
        usleep(r);
        pthread_create(&pid, NULL, runner, NULL);
    }
    
    return 0;
}
 
 
void* runner(void* params){
    unsigned int nr = richiesta(); // Richiedi numero di risorsa libera
    // Lavora sui dati
    elabora(nr); // Elabora i dati, la mutua escusione è implicitamente utilizzata con richiesta() e rilascia()
    // Rilascia le risorse
    rilascia(nr);
 
    
}
 
unsigned int richiesta(){
    sem_wait(&s_nrisorselibere); // Attendo che ci sia almeno una risorsa libera
    unsigned int retvalue = 0;
    pthread_mutex_lock(&m_BMrisorsacondivisa);
    for(int i=0;i<R && (retvalue == 0);++i){ // Break al primo valore 0 che trova
        if(BMrisorsacondivisa[i] == 0) // Ciò significa che l'iesima risorsa è libera
            retvalue = i;
    }
    pthread_mutex_unlock(&m_BMrisorsacondivisa);
    return retvalue;
}
 
void rilascia(int x){
    pthread_mutex_lock(&m_BMrisorsacondivisa);
    BMrisorsacondivisa[x] = 0;
    pthread_mutex_unlock(&m_BMrisorsacondivisa);
    sem_post(&s_nrisorselibere);
}

Comments

  •  icon
    01/01/70 12:00:00 AM UTC
    Plain Text |

    0 B

    |

    👍

    /

    👎

    
        
  •  icon
    01/01/70 12:00:00 AM UTC
    Plain Text |

    0 B

    |

    👍

    /

    👎