INFOPedia : LSOMutexTreniPthread

HomePage :: Categorie :: Indice :: Ultime modifiche :: Ultimi commenti :: Login/Registrazione
Questo è il problema dei 3 treni già visto nelle pagine Problema dei treni ma fatto attraverso la libreria pthread di unix.
In questa implementazione sono stati usati un vettore di 2 puntatori, "binari[2]", che serve a memorizzare l'indirizzo ai vettori "Andata" e "Ritorno" ed evitare ripetizioni di codice per gestire l'andata e il ritorno del treno; e il vettore "percorso" e "tratta" che servono solamente a scrivere correttamente a video in che direzione sta andando il treno, ma non ha nessuna necessità ai fini del funzionamento della sincronizzazione dei processi.

Il testo del problema:



Tre treni T1 e T2 T3 collegano tre stazioni A B e C su una tratta a singolo binario.
T1 fa la spola tra A e C,T2 fa la spola tra A e B , e T3 tra B e C. I Treni possono viaggiare contemporaneamente sulla stessa linea solo se stanno andando nella stessa direzione. T1 ha priorità rispetto al treno T2 e T3 ossia se T1 non dovra mai fermarsi alla stazione B per aspettare T1 o T2.

I treni partono dopo avere atteso alla stazione un dato tempo (TIMET1 e TIMET2 e TIMET3) e percorrono le tratte alla stessa velocità , quindi T1 impegna 2*k minuti, T2 e T3 k minuti.


1. Scrivere il programma Treni in C che abbia le i seguenti processi:
T1 ();
T2();
T3()
Il programma deve soddisfare alle seguenti caratteristiche:
a) assenza di deadlock
b) assenza di scontri.

2. Spiegare come le proprietà a e b sono rispettate dal vostro algoritmo.

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

#define ABSX(x) x>0 ? x : -x     // macro che calcola il valore assoluto di un intero x
#define t 1                //tempo di percorrenza
#define TIMET1 3        //tempo di attesa treno 1
#define TIMET2 6        //tempo di attesa treno 2
#define TIMET3 6        //tempo di attesa treno 3

pthread_mutex_t h_mutexcs;      // mutex per proteggere la modifica dei vettori andata e ritorno
pthread_mutex_t h_print;           // mutex per proteggere la scrittura a video
pthread_t h_finito,h_treni[3];

char *percorso[2];
char *tratta[6];
int andata[2], ritorno[2], *binari[2];

void finito(void *end);
void T1(void *end);
void T2(void *end);
void T3(void *end);

//=================================//
//              MAIN
//=================================//

int main()
{
        int fine=0,i;

        pthread_mutex_init(&h_mutexcs,NULL);        //inizializza il mutex per la sezione critica
        pthread_mutex_init(&h_print,NULL);                   //inizializza il mutex per la stampa a video

        percorso[0]=(char *)malloc(7*sizeof(char));
        percorso[0]="ANDATA";
        percorso[1]=(char *)malloc(8*sizeof(char));
        percorso[1]="RITORNO";
        tratta[0]=(char *)malloc(5*sizeof(char));
        tratta[0]="A->C";
        tratta[1]=(char *)malloc(5*sizeof(char));
        tratta[1]="C->A";
        tratta[2]=(char *)malloc(5*sizeof(char));
        tratta[2]="A->B";
        tratta[3]=(char *)malloc(5*sizeof(char));
        tratta[3]="B->A";
        tratta[3]="B->A";
        tratta[4]=(char *)malloc(5*sizeof(char));
        tratta[4]="B->C";
        tratta[5]=(char *)malloc(5*sizeof(char));
        tratta[5]="C->B";


        for(i=0; i<2; i++)
                andata[i]=ritorno[i]=0;           // inzializza i vettori andata e ritorno

        binari[0]=andata;                      //il primo elemento di binari punta al vettore andata
        binari[1]=ritorno;                          //il secondo elemento di binari punta al vettore ritorno
       
       
        pthread_create(&h_finito,NULL,finito,&fine);
        pthread_create(&h_treni[0],NULL,T1,&fine);
        pthread_create(&h_treni[1],NULL,T2,&fine);
        pthread_create(&h_treni[2],NULL,T3,&fine);
               pthread_join(h_finito,NULL);                         //condizione di terminazione
        pthread_join(h_treni[0],NULL);                //condizione di terminazione
        pthread_join(h_treni[1],NULL);                //condizione di terminazione
        pthread_join(h_treni[2],NULL);                //condizione di terminazione
        return 0;
}

void finito(void *end)
{
        int *fine;
        fine=(int*) end;
        getchar();
        *fine=1;       
}



//=================================//
//             TRENO 1    (A-C)
//=================================//

void T1(void *end)
{
    int *fine;
    int ar=0;                  //0 andata, 1 ritorno
    int id=0;                  //serve ad identificare il treno nei printf
    int flag=0;
    fine=(int*) end;        //serve solo a castare FINE
   

    while (*fine==0)
    {
       
        pthread_mutex_lock(&h_mutexcs);

        //binari[andata o ritorno][AB] è libero &&  binari[andata o ritorno][BC] è libero
        if ( (binari[ABSX((ar-1))][0]==0) && (binari[ABSX((ar-1))][1]==0) )
        {           
            binari[ar][0]++;      //blocco il binario AB (0) di andata o ritorno (ar)
            binari[ar][1]++;      //blocco il binario BC (1) di andata o ritorno (ar)
            flag=1;
        }

        pthread_mutex_unlock(&h_mutexcs);
       
        if (flag)
        {
       
            pthread_mutex_lock(&h_print);
                printf("Il treno T1 sta percorrendo la tratta %s in %s\n", tratta[(2*id) + ar], percorso[ar]);
            pthread_mutex_unlock(&h_print);

            sleep(2*t);                //tempo di percorrenza

            pthread_mutex_lock(&h_print);
                printf("Il treno T1 e' arrivato a destinazione\n");
            pthread_mutex_unlock(&h_print);

            pthread_mutex_lock(&h_mutexcs);
   
                binari[ar][0]--;        //sblocco il binario AB di andata o ritorno
                binari[ar][1]--;        //sblocco il binario BC di andata o ritorno
                ar=ABSX((ar-1));         //se sto andando devo tornare, e viceversa

            pthread_mutex_unlock(&h_mutexcs);
        
            sleep(TIMET1);                   //resta alla stazione per un determinato periodo di tempo
            flag=0;
        }
        else
            sleep(0);
    }
}

//=================================//
//             TRENO 2    (A-B)
//=================================//


void T2(void *end)
{
    int *fine;
    int ar=0;            //0 andata, 1 ritorno
    int id=1;            //serve ad identificare il treno nei printf
    int flag=0;
    fine=(int*) end;         //serve solo a castare FINE
   

    while (*fine==0)
    {
               
        pthread_mutex_lock(&h_mutexcs);
       
        if ( binari[ABSX((ar-1))][0]==0 )    //binari[andata-ritorno][AB] è libero
        {           
            binari[ar][0]++;             //blocco il binario AB di andata o ritorno
            flag=1;
        }

        pthread_mutex_unlock(&h_mutexcs);
       
        if (flag)
        {
            pthread_mutex_lock(&h_print);
                printf("Il treno T2 sta percorrendo la tratta %s in %s\n", tratta[(2*id) + ar], percorso[ar]);
            pthread_mutex_unlock(&h_print);

            sleep(t);                //tempo di percorrenza

            pthread_mutex_lock(&h_print);
                printf("Il treno T2 e' arrivato a destinazione\n");
            pthread_mutex_unlock(&h_print);

            pthread_mutex_lock(&h_mutexcs);
   
                binari[ar][0]--;           //sblocco il binario AB di andata o ritorno
                ar=ABSX((ar-1));        //se sto andando devo tornare, e viceversa

            pthread_mutex_unlock(&h_mutexcs);
        
            sleep(TIMET2);                //resta alla stazione per un determinato periodo di tempo
           
            flag=0;
        }
        else
            sleep(0);
    }
}

//=================================//
//             TRENO 3
//=================================//

void T3(void *end)
{
    int *fine;
    int ar=0;            //0 andata, 1 ritorno
    int id=2;            //serve ad identificare il treno nei printf
    int flag=0;
    fine=(int*) end;         //serve solo a castare FINE
   
    while (*fine==0)
    {
               
        pthread_mutex_lock(&h_mutexcs);
       
        if ( (binari[ABSX((ar-1))][1]==0))    //binari[andata-ritorno][BC] è libero
        {           
            binari[ar][1]++;             //blocco il binario BC di andata o ritorno
            flag=1;
        }

        pthread_mutex_unlock(&h_mutexcs);
       
        if (flag)
        {
            pthread_mutex_lock(&h_print);
                printf("Il treno T3 sta percorrendo la tratta %s in %s\n", tratta[(2*id) + ar], percorso[ar]);
            pthread_mutex_unlock(&h_print);

            sleep(t);                //tempo di percorrenza
   
            pthread_mutex_lock(&h_print);
                printf("Il treno T3 e' arrivato a destinazione\n");
            pthread_mutex_unlock(&h_print);

            pthread_mutex_lock(&h_mutexcs);
   
                binari[ar][1]--;           //sblocco il binario AB di andata o ritorno
                ar=ABSX((ar-1));        //se sto andando devo tornare, e viceversa

            pthread_mutex_unlock(&h_mutexcs);
        
            sleep(TIMET3);                //resta alla stazione per un determinato periodo di tempo
       
            flag=0;           
        }
        else
            sleep(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.3878 secondi