Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /* 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);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement