INFOPedia : LSOPonteTibetano1

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

Ponte Tibetano 1


// L'algoritmo dovrebbe esser corretto, sono tuttavia convinto che ci sia un'anomalia nel controllo del peso.
// A mio parere sorge dall'utilizzo di un HANDLE temporaneo che ad ogni ciclo viene sovrascritto!
// Tento di risolvere...inserendo il controllo Peso dopo la creazione di ogni singolo Thread.
// A volte il programma sembra vada in deadlock...penso sia legato ai timeout...cmq...il 90% delle volte funziona.
#include <conio.h>
#include <ctype.h>
#include <time.h>
#include <windows.h>
#include <stdio.h>
#include <process.h>

#define MAXPESO 1000 // Peso massimo sostenibile dal ponte
#define PESOP 150    // Peso di una persona Standard
#define PESOC 300    // Peso di un carro Standard
#define ANDATA 0     // ANDATA
#define RITORNO 1    // RITORNO
#define GetRandom(min, max) ((rand() % (int)(((max) +1) - (min))) + (min)) // Funzione di Generazione interi casuali

// Le seguenti variabili globali saranno protette da Mutex!
int PesoAttuale = 0;    // Var. Glob. per il Peso Attuale sul ponte
int Persone[2] = {0,0}; // Var. Glob. per il Conteggio Persone sul ponte

// Funzioni Thread.
void Pedone(LPDWORD lpdwParam); // Un Pedone.
void Carro(LPDWORD lpdwParam); // Un Carro.

// Handle globali dei semafori e dei mutex: Semafori Corsie, Mutex Var. Glob., Mutex Stream di Output
HANDLE hCorsiaA[2], hCorsiaR[2], hPeso, hPersone, hPrint;

// Inizia il programmino...=)
void main() {
    // Conteggio Thread e cicli di wait per il peso.
    int c,count = 0;
    c= count;
    // Var. Flag per la destinazione
    int A = ANDATA;
    int R = RITORNO;
    srand((unsigned)time(NULL)); // Generazione del seed per il rand
    // Creo i Mutex e i Semafori
    hPeso = CreateMutex(NULL,false,NULL);
    hPersone = CreateMutex(NULL,false,NULL);
    hPrint = CreateMutex(NULL,false,NULL);
    for( int i = 0; i<2; i++ ) {
        // NB: Ho utilizzato i semafori per essere sicuro di ottenere il numero di corsia giusto all'interno dei thread.
        hCorsiaA[i] = CreateSemaphore(NULL,1,1,NULL);
        hCorsiaR[i] = CreateSemaphore(NULL,1,1,NULL);
    }
   
    HANDLE hNow; // Handle temporaneo per il resume dei thread.
   
    printf("Pressa un tasto per generare un carro o un pitone. q per uscire.\n");
    // Comincia il ciclo di creazione dei Thread :|
    do{
        if(GetRandom(0,1)) {  // Creo un Carro se GetRandom ritorna 1
            if(GetRandom(0,1)){ // La destinazione è ANDATA se il GetRandom ritorna 1
                WaitForSingleObject(hPrint,INFINITE);
                printf("Il Carro vuole andare! Peso attuale: %d\n",PesoAttuale);
                ReleaseMutex(hPrint);
                hNow = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE) Carro,(LPVOID) &(A), CREATE_SUSPENDED,NULL);
                c++;
                do{ // Inizia il ciclo per il controllo Peso
                    if(PesoAttuale+PESOC<MAXPESO) { // Controllo peso: OK
                        ResumeThread(hNow);
                        break;
                    } else { // Controllo Peso: NOK
                        count++;
                        WaitForSingleObject(hPrint,INFINITE);
                        printf("Peso Massimo raggiunto, Aspetto! Peso Attuale: %d - Ho aspettato %d volte\n", PesoAttuale,count);
                        ReleaseMutex(hPrint);
                        Sleep(10000); // Aspetto un pochito! =)
                        continue;
                    }
                }while(1); count =0; // Fine del ciclo di controllo Peso
            } else { // La destinazione è RITORNO se il GetRandom ritorna 0
                WaitForSingleObject(hPrint,INFINITE);
                printf("Il Carro vuole tornare! Peso attuale: %d\n",PesoAttuale);
                ReleaseMutex(hPrint);
                hNow = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE) Carro,(LPVOID) &(R), CREATE_SUSPENDED,NULL);
                c++;
                do{ // Inizia il ciclo per il controllo Peso
                    if(PesoAttuale+PESOC<MAXPESO) { // Controllo peso: OK
                        ResumeThread(hNow);
                        break;
                    } else { // Controllo Peso: NOK
                        count++;
                        WaitForSingleObject(hPrint,INFINITE);
                        printf("Peso Massimo raggiunto, Aspetto! Peso Attuale: %d - Ho aspettato %d volte\n", PesoAttuale,count);
                        ReleaseMutex(hPrint);
                        Sleep(10000); // Aspetto un pochito! =)
                        continue;
                    }
                }while(1); count =0; // Fine del ciclo di controllo Peso
            }
           
        } else { // Creo un Pedone se GetRandom ritorna 0
            if(GetRandom(0,1)){ // La destinazione è ANDATA se il GetRandom ritorna 1
                WaitForSingleObject(hPrint,INFINITE);
                printf("Il Pedone vuole andare! Peso attuale: %d\n",PesoAttuale);
                ReleaseMutex(hPrint);
                hNow = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE) Pedone,(LPVOID) &(A), CREATE_SUSPENDED,NULL);
                c++;
                do{ // Inizia il ciclo per il controllo Peso
                    if(PesoAttuale+PESOP<MAXPESO) { // Controllo peso: OK
                        ResumeThread(hNow);
                        break;
                    } else { // Controllo Peso: NOK
                        count++;
                        WaitForSingleObject(hPrint,INFINITE);
                        printf("Peso Massimo raggiunto, Aspetto! Peso Attuale: %d - Ho aspettato %d volte\n", PesoAttuale,count);
                        ReleaseMutex(hPrint);
                        Sleep(10000); // Aspetto un pochito! =)
                        continue;
                    }
                }while(1); count =0; // Fine del ciclo di controllo Peso
            } else { // La destinazione è RITORNO se il GetRandom ritorna 1
                WaitForSingleObject(hPrint,INFINITE);
                printf("Il Pedone vuole tornare! Peso attuale: %d\n",PesoAttuale);
                ReleaseMutex(hPrint);
                hNow = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE) Pedone,(LPVOID) &(R), CREATE_SUSPENDED,NULL);
                c++;
                do{ // Inizia il ciclo per il controllo Peso
                    if(PesoAttuale+PESOP<MAXPESO) { // Controllo peso: OK
                        ResumeThread(hNow);
                        break;
                    } else { // Controllo Peso: NOK
                        count++;
                        WaitForSingleObject(hPrint,INFINITE);
                        printf("Peso Massimo raggiunto, Aspetto! Peso Attuale: %d - Ho aspettato %d volte\n", PesoAttuale,count);
                        ReleaseMutex(hPrint);
                        Sleep(10000); // Aspetto un pochito! =)
                        continue;
                    }
                }while(1); count =0; // Fine del ciclo di controllo Peso
            }
        }
    } while(getch()!='q')// Fine del ciclo di creazione Thread!!! :|
    printf("\n*) Numero Persone sulle corsie: %d\n*) Peso Attuale: %d\nHo creato %d thread!\n\n",Persone[0]+Persone[1],PesoAttuale,c); // Riassuntino finale
}

void Pedone(LPDWORD lpdparm){
    DWORD result; // Variabile per il risultato dei Wait.
    int nCorsia;  // Numero corsia assegnata
    int dst = *(int *) lpdparm; // Destinazione del viaggio
   
    if(dst==0) { // Caso destinazione ANDATA
        // Assegno un numero di corsia.
        result = WaitForMultipleObjects(2,hCorsiaR,false,INFINITE);
        nCorsia = result - WAIT_OBJECT_0 +1;
        // Caso in cui non vi siano persone sulla stessa corsia
        if(Persone[nCorsia-1]==0) WaitForSingleObject(hCorsiaA[nCorsia-1],INFINITE); // Occupo la corsia di andata.
        // Rilascio quella di ritorno. Permetto ad altri di procedere nello stesso senso
        ReleaseSemaphore(hCorsiaR[nCorsia-1],1,NULL);

        WaitForSingleObject(hPeso,INFINITE);
        PesoAttuale+=PESOP; // Una persona in più --> Aumento Peso
        ReleaseMutex(hPeso);
        WaitForSingleObject(hPersone,INFINITE);
        Persone[nCorsia-1]++; // Una persona in più --> Aumento Persone sulla corsia.
        ReleaseMutex(hPersone);
        WaitForSingleObject(hPrint,INFINITE);
        printf("Il Pedone e' partito (ANDATA). Numero Corsia: %d\n",nCorsia);
        ReleaseMutex(hPrint);
        Sleep(5000); // Persona in viaggio di ANDATA
        WaitForSingleObject(hPrint,INFINITE);
        printf("Il Pedone e' arrivato(ANDATA). Numero Corsia: %d\n",nCorsia);
        ReleaseMutex(hPrint);
        WaitForSingleObject(hPersone,INFINITE);
        Persone[nCorsia-1]--; // Una persona in meno --> Diminuisco Persone sulla corsia
        ReleaseMutex(hPersone);
        WaitForSingleObject(hPeso,INFINITE);
        PesoAttuale-=PESOP; // Una persona in meno --> Diminuisco Peso
        ReleaseMutex(hPeso);
        // Caso in cui non vi siano persone sulla corsia
        // Rilascio la corsia di andata. Permetto ad altri di tornare.
        if(Persone[nCorsia-1]==0) ReleaseSemaphore(hCorsiaA[nCorsia-1],1,NULL);
        WaitForSingleObject(hPrint,INFINITE);
        // Riassuntino... =)
        printf("\n*) Numero Persone sulle corsie: %d\n*) Peso Attuale: %d\n\n",Persone[0]+Persone[1],PesoAttuale);
        ReleaseMutex(hPrint);
    }
    else { // Caso destinazione RITORNO
        // Assegno un numero di corsia.
        result = WaitForMultipleObjects(2,hCorsiaA,false,INFINITE);
        nCorsia = result - WAIT_OBJECT_0+1;
        // Caso in cui non vi siano persone sulla stessa corsia
        if(Persone[nCorsia-1]==0) WaitForSingleObject(hCorsiaR[nCorsia-1],INFINITE)// Occupo la corsia di ritorno
        // Rilascio quella di andata. Permetto ad altri di procedere nello stesso senso
        ReleaseSemaphore(hCorsiaA[nCorsia-1],1,NULL);
       
        WaitForSingleObject(hPersone,INFINITE);
        Persone[nCorsia-1]++; // Una persona in più --> Aumento Peso
        ReleaseMutex(hPersone);
        WaitForSingleObject(hPeso,INFINITE);
        PesoAttuale+=PESOP; // Una persona in più --> Aumento Persone sulla corsia.
        ReleaseMutex(hPeso);
       
        WaitForSingleObject(hPrint,INFINITE);
        printf("Il Pedone e' partito (RITORNO). Numero Corsia: %d\n",nCorsia);
        ReleaseMutex(hPrint);
        Sleep(5000); // Persona in viaggio di RITORNO
        WaitForSingleObject(hPrint,INFINITE);
        printf("Il Pedone e' arrivato(RITORNO). Numero Corsia: %d\n",nCorsia);
        ReleaseMutex(hPrint);
        WaitForSingleObject(hPersone,INFINITE);
        Persone[nCorsia-1]--; // Una persona in meno --> Diminuisco Persone sulla corsia
        ReleaseMutex(hPersone);
        WaitForSingleObject(hPeso,INFINITE);
        PesoAttuale-=PESOP; // Una persona in meno --> Diminuisco Peso
        ReleaseMutex(hPeso);
        // Caso in cui non vi siano persone sulla corsia
        // Rilascio la corsia di ritorno. Permetto ad altri di andare.
        if(Persone[nCorsia-1]==0) ReleaseSemaphore(hCorsiaR[nCorsia-1],1,NULL);
        WaitForSingleObject(hPrint,INFINITE);
        // Riassuntino... =)
        printf("\n*) Numero Persone sulle corsie: %d\n*) Peso Attuale: %d\n\n",Persone[0]+Persone[1],PesoAttuale);
        ReleaseMutex(hPrint);
    }
   
}

void Carro(LPDWORD lpdparm){
    DWORD result; // In questo caso è superfluo
    int dst = *(int *) lpdparm; // Destinazione del viaggio
   
    if(dst==0) { // Caso destinazione ANDATA
        // Occupo entrambe le corsie.
        result = WaitForMultipleObjects(2,hCorsiaR,true,INFINITE);
        if(Persone[0] == 0) WaitForSingleObject(hCorsiaA[0],INFINITE);
        if(Persone[1] == 0) WaitForSingleObject(hCorsiaA[1],INFINITE);
        // Rilascio entrambe le corsie di ritorno per permettere ad altri di accodarsi.
        ReleaseSemaphore(hCorsiaR[0],1,NULL);
        ReleaseSemaphore(hCorsiaR[1],1,NULL);

        WaitForSingleObject(hPeso,INFINITE);
        PesoAttuale+=PESOC; // Aggiungo il peso di un Carro
        ReleaseMutex(hPeso);
       
        WaitForSingleObject(hPersone,INFINITE);
        // Un carro vale due persone!!! Aggiungo due persone
        Persone[0]++;
        Persone[1]++;
        ReleaseMutex(hPersone);
               
        WaitForSingleObject(hPrint,INFINITE);
        printf("Il Carro e' partito (ANDATA).\n");
        ReleaseMutex(hPrint);
        Sleep(5000); // Carro in viaggio di ANDATA
        WaitForSingleObject(hPrint,INFINITE);
        printf("Il Carro e' arrivato(ANDATA).\n");
        ReleaseMutex(hPrint);
        WaitForSingleObject(hPersone,INFINITE);
        // Un carro vale due persone!!! Tolgo due persone
        Persone[0]--;
        Persone[1]--;
        ReleaseMutex(hPersone);
        WaitForSingleObject(hPeso,INFINITE);
        PesoAttuale-=PESOC; // Tolgo il Peso di un Carro
        ReleaseMutex(hPeso);
        // Caso in cui non ci son persone in entrambe le corsie
        // Rilascio entrambe le corsie di andata, per permettere ad altri di tornare.
        if(Persone[0]==0) ReleaseSemaphore(hCorsiaA[0],1,NULL);
        if(Persone[1]==0) ReleaseSemaphore(hCorsiaA[1],1,NULL);
       
        WaitForSingleObject(hPrint,INFINITE);
        // Riassuntino... =)
        printf("\n*) Numero Persone sulle corsie: %d\n*) Peso Attuale: %d\n\n",Persone[0]+Persone[1],PesoAttuale);
        ReleaseMutex(hPrint);
    }
    else { // Caso destinazione RITORNO
        // Occupo entrambe le corsie.
        result = WaitForMultipleObjects(2,hCorsiaA,true,INFINITE);
        if(Persone[0] == 0) WaitForSingleObject(hCorsiaR[0],INFINITE);
        if(Persone[1] == 0) WaitForSingleObject(hCorsiaR[1],INFINITE);
       
        WaitForSingleObject(hPeso,INFINITE);
        PesoAttuale+=PESOC; // Aggiungo il peso di un Carro
        ReleaseMutex(hPeso);
       
        WaitForSingleObject(hPersone,INFINITE);
        // Un carro vale due persone!!! Aggiungo due persone
        Persone[0]++;
        Persone[1]++;
        ReleaseMutex(hPersone);
       
        // Rilascio entramebe le corsie di andata per permettere ad altri di accodarsi.
        ReleaseSemaphore(hCorsiaA[0],1,NULL);
        ReleaseSemaphore(hCorsiaA[1],1,NULL);
       
        WaitForSingleObject(hPrint,INFINITE);
        printf("Il Carro e' partito (RITORNO).\n");
        ReleaseMutex(hPrint);
        Sleep(5000); // Carro in viaggio di RITORNO
        WaitForSingleObject(hPrint,INFINITE);
        printf("Il Carro e' arrivato(RITORNO).\n");
        ReleaseMutex(hPrint);
        WaitForSingleObject(hPersone,INFINITE);
        // Un carro vale due persone!!! Tolgo due persone
        Persone[0]--;
        Persone[1]--;
        ReleaseMutex(hPersone);
        WaitForSingleObject(hPeso,INFINITE);
        PesoAttuale-=PESOC; // Tolgo il Peso di un Carro
        ReleaseMutex(hPeso);
        // Caso in cui non ci son persone in entrambe le corsie
        // Caso in cui non ci son persone in entrambe le corsie
        // Rilascio entrambe le corsie di andata, per permettere ad altri di tornare.
        if(Persone[0]==0) ReleaseSemaphore(hCorsiaR[0],1,NULL);
        if(Persone[1]==0) ReleaseSemaphore(hCorsiaR[1],1,NULL);

        WaitForSingleObject(hPrint,INFINITE);
        // Riassuntino... =)
        printf("\n*) Numero Persone sulle corsie: %d\n*) Peso Attuale: %d\n\n",Persone[0]+Persone[1],PesoAttuale);
        ReleaseMutex(hPrint);
    }
   
   
}


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.5819 secondi