INFOPedia : LSOMutexAutolavaggioPthread

HomePage :: Categorie :: Indice :: Ultime modifiche :: Ultimi commenti :: Login/Registrazione

Autolavaggio UNIX


Ho risolto il problema d'esame del 15-02-06, insomma Autolavaggi.
Dato che è stato già risolto utilizzando i thread e mutex sotto Windows, ho pensato bene di implementarlo in Unix utilizzando le pthread e i mutex.

Di seguito il codice sorgente:

// Includo le librerie.
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>

// Costanti e funzioni utili
#define N 3
#define T 1
#define GetRandom( min, max ) ((rand( ) % (int)(((max) + 1) - (min))) + (min))

// Variabile che conterrà il nome del programma (inutile)
char *progname;

/* I lavaggi e l'attributo da passare all'inizializzatore del mutex! */
pthread_mutex_t hLavaggi[N];
pthread_mutexattr_t attr; // UTILISSIMO!!!

/* print error message and die */
void error(char *f){
    extern char *progname;
    if (progname)
        fprintf(stderr, "%s: ", progname);
    perror(f);
    exit(1);
}

/* suspend execution of the calling thread */
void waiting(int min, int max){
    sleep(rand()%(max-min+1) + min);
}

// Routine comune ad ogni thread!
void *CarRoutine(void *param){
    int id=*(int *)param; // id del thread
    int type = GetRandom(1,2); // tipo di macchina

    if( type == 1 ) { // caso di una macchina NORMALE
        printf("T%d: Sono una macchina NORMALE! Aspetto un lavaggio!\n", id);
        while(1) { // cicla fino a trovare un lavaggio!
            // se trova il lavaggio 3 libero lo blocca altrimenti non si blocca ma continua, grazie alla funzione del trylock
            if ( pthread_mutex_trylock(&hLavaggi[2]) == 0 ) {
                printf("T%d: Sono entrato nel lavaggio 3!\n", id);
                waiting(T*3,T*3); // attende...
                pthread_mutex_unlock(&hLavaggi[2]); // rilascia il mutex
                printf("T%d: Sono uscito dal lavaggio 3! Sono una NORMALE\n", id);
                break; // Interrompe il ciclo
            }
            // vedi sopra
            if ( pthread_mutex_trylock(&hLavaggi[1]) == 0 ) {
                printf("T%d: Sono entrato nel lavaggio 2!\n", id);
                waiting(T*2,T*2);
                pthread_mutex_unlock(&hLavaggi[1]);
                printf("T%d: Sono uscito dal lavaggio 2! Sono una NORMALE\n", id);
                break;
            }
            // vedi sopra
            if ( pthread_mutex_trylock(&hLavaggi[0]) == 0 ) {
                printf("T%d: Sono entrato nel lavaggio 1!\n", id);
                waiting(T,T);
                pthread_mutex_unlock(&hLavaggi[0]);
                printf("T%d: Sono uscito dal lavaggio 1! Sono una NORMALE\n", id);
                break;
            }
        } // fine ciclo while(1). la macchina è pulita!
    }
    if( type == 2 ) { // caso di una macchina GRANDE
        printf("T%d: Sono una macchina GRANDE! Aspetto il lavaggio 1!\n", id);
        while(1) { // cicla finche non ottiene il lavaggio 1
            if ( pthread_mutex_trylock(&hLavaggi[0]) == 0 ){
                printf("T%d: Sono entrato nel lavaggio 1! Sono una GRANDE\n", id);
                waiting(T,T);
                pthread_mutex_unlock(&hLavaggi[0]);
                printf("T%d: Sono uscito dal lavaggio 1! Sono una GRANDE\n", id);
                break;
            } else {
                printf("T%d: Lavaggio 1 occupato! Sono una GRANDE e aspetto...\n", id);
                waiting(T,T);
            }
        }
    }
    return NULL;
}

// Inizia il programmino...
int main(int argc, char *argv[])
{
    // Inizializzo l'attributo del mutex
    pthread_mutexattr_init(&attr);
    // Mutex di tipo ERRORCHECK
    pthread_mutexattr_settype(&attr,PTHREAD_MUTEX_ERRORCHECK);
    int i;
    // Struttura di un thread car
    struct  {
        int id;
        pthread_t thread_id;
    } car;
   
    // Questo è il nome del programmino
    progname=argv[0];
    // Via al semeeeeeeee
    srand(time(NULL));
   
    /* create mutex di tipo ERRORCHECK */
    for (i=0; i<N; i++)
        if (pthread_mutex_init(&hLavaggi[i], &attr))
            error("pthread_mutex_init");
    i = 0;
    /* create and run the threads */
    do { // Pronti...VIAAAAA
        car.id=i; // id del prossimo thread
        if (pthread_create(&car.thread_id, NULL, CarRoutine, &car.id))
            error("pthread_create");
        i++; // altro thread
    } while (getchar() != 'q'); // finchè non presso q + invio...
   
    return 0;
}




Torna a Lab Sistemi Operativi

Non ci sono commenti in questa pagina. [Scrivi commento]

Valid XHTML 1.0 Transitional :: Valid CSS :: Powered by Wikka Wakka Wiki 1.1.6.1
La pagina è stata generata in 0.1545 secondi