INFOPedia : LSOElettori

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

Elettori e Presidente (Cuffaro...)


Si consideri un seggio elettorale dotato di un presidente e N cabine elettorali (non si considerino gli scrutatori).
La vita di elettori e presidente è la seguente:
Presidente
{while (non sono ancora le 22)
{consegnaScheda();
            consegnaMatita();
}
}
 
 Elettore
{attendiScheda();
int cid = seggio.attendiCabina();
/* cid=0..N-1 è il numero di cabina */
/* Rifletti bene prima di votare... */
/* Riflettici ancora un po'... */
/* Vota! */
esciCabina(cid);
}

In altre parole, l'elettore arriva al seggio e attende che il presidente gli consegni una scheda per votare. Ovviamente, nei periodi di poco afflusso può essere il presidente a dover attendere gli elettori. Un volta ottenuta la scheda, l'elettore deve attendere che gli sia consegnata (da parte del presidente) una matita numerata, corrispondente alla cabina.
Data la struttura del Presidente, in ogni istante vi può essere al più un solo elettore in possesso di scheda ma in attesa di matita.
Ovviamente, le cabine possono essere assegnate ad un solo elettore alla volta. Quando l'elettore esce da una cabina, notifica il presidente (riconsegnando la matita); il presidente può quindi consegnare la matita all'eventuale elettore in attesa di matita.

Si sviluppi il programma che simuli la situazione precedente considerando le funzioni Presidente e Elettore come threads di un unico processo:

a) descrivere le scelte fatte e giustificarle.
b) scrivere il codice delle funzioni presidente e elettore in C in ambiente windows o linux.
c) motivare l’assenza di deadlock.

//----------------------------------------------------------------------------------------------------------------
// Importo le librerie necessarie...
//----------------------------------------------------------------------------------------------------------------
#include <windows.h>
#include <time.h>
#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>



//----------------------------------------------------------------------------------------------------------------
// Dichiaro le costanti e le variabili globali...
//----------------------------------------------------------------------------------------------------------------
#define __N_matite 5                            //Definisco un numero arbitrario di matite,che corrispondono alle cabine elettorali
HANDLE H_Semaphore_Scheda;                      //Handle del semaforo per le schede elettorali
HANDLE H_Mutex_Matita[__N_matite];                //Handle del semaforo per le matite,ogni matita corrisponde ad una cabina elettorale
HANDLE H_Thread_Presidente;                     //Handle al thread presidente                   
CRITICAL_SECTION accura;                        //Creo una critical section
int __N_Elettori=0;                             //variabile globale che indica il numero di elettori attualmente presenti al seggio elettorale
int Mutex_Matita_occupata[__N_matite];          //Creo un array per sapere quali mutex sono stati rilasciati.
int conta_schede = __N_matite + 1;              //contatore per le schede
int arrivato=0;                                 //indica l'arrivo del presidente,se non c'Ë nessuno puÚ votare
int fine=0;                                        //Utilizzata dal Thread per la fine


//----------------------------------------------------------------------------------------------------------------
// Dichiaro le funzioni e le procedure...
//----------------------------------------------------------------------------------------------------------------
#define GetRandom( min, max ) ((rand() % (int)(((max) + 1) - (min))) + (min))
#define randomize srand((unsigned)time(NULL))

HANDLE Finito(LPDWORD lpdwParam);
void Elettore(int *count);
void Presidente(int *fine);



//----------------------------------------------------------------------------------------------------------------
// Main...
//----------------------------------------------------------------------------------------------------------------
void main()
{
    int count = 0;

    //Inizializzo la critical section
    InitializeCriticalSection(&accura);

    //Creo il thread per gestire la fine...
    CreateThread(NULL,0,(LPTHREAD_START_ROUTINE) Finito,(LPVOID) &fine,0,NULL);
   
    //Creo il thread Presidente
    H_Thread_Presidente = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE) Presidente,(LPVOID) &fine,0,NULL);

    //Aspetto che il Thread presidente abbia svolto le azioni basilari
    while (arrivato == 0);

    while (fine == 0)
    {
        CreateThread(NULL,0,(LPTHREAD_START_ROUTINE) Elettore ,(LPVOID) &count ,0, NULL);
        Sleep(GetRandom(2000,3000));   
        count++;
    }
}



void Presidente(int *fine)
{
    //Creo il semaforo per le schede elettorali,e faccio in modo che le schede siano tutte in possesso del Presidente
    H_Semaphore_Scheda = CreateSemaphore(NULL,0,( __N_matite + 1),NULL);

    //Creo l'array di mutex per le matite,e faccio in modo che le matite siano tutte in possesso del presidente
    for (int i=0;i<__N_matite;i++)
    {
        H_Mutex_Matita[i] = CreateMutex(NULL,true,NULL);
        Mutex_Matita_occupata[i] = 1;
    }

    //Abilito l'accesso al seggio elettorale
    arrivato = 1;

    while (*fine == 0)
    {
        if (__N_Elettori > 0)  // Controlla se ci sono elettori al seggio
        {
            EnterCriticalSection(&accura);

                //Il presidente consegna una scheda all'elettore...
                if ( (conta_schede > 0) && (ReleaseSemaphore(H_Semaphore_Scheda,1,NULL)) )
                {
                    printf("*** Presidente *** consegno una scheda all'elettore...\n");
                    conta_schede--;
                   
                    i=0;
                    int trovato = 0;
                   
                    while ((i<__N_matite) && (trovato == 0))
                    {
                        if (Mutex_Matita_occupata[i] == 1)
                        {
                            trovato = 1; //permette di uscire dal while
                            ReleaseMutex(H_Mutex_Matita[i]);
                            Mutex_Matita_occupata[i] = 0; // Il presidente rende disponibile la matita per un elettore

                            printf("*** Presidente *** consegno una matita all'elettore...\n");
                        }
                        i++;
                    }
                printf("*** Presidente *** l'elettore e' stato servito...\n");
                }

                __N_Elettori--;
            LeaveCriticalSection(&accura);
        }
    }
}

void Elettore(int *count)
{
    int num = *count;
    DWORD result,pos;
   
    EnterCriticalSection(&accura); //arrivo di un elettore
        __N_Elettori++;
        printf("*** Elettore *** e' arrivato l'elettore%d...\n", num);
    LeaveCriticalSection(&accura);

    if ( WaitForSingleObject(H_Semaphore_Scheda,INFINITE) != WAIT_ABANDONED ) //Occupa una scheda rilasciata dal presidente
    {
        EnterCriticalSection(&accura);
            printf("*** Elettore%d *** prende una scheda\n",num);
        LeaveCriticalSection(&accura);

        result = WaitForMultipleObjects(__N_matite,H_Mutex_Matita,false,INFINITE); // Occupa una matita rilasciata dal presidente
            pos = result - WAIT_OBJECT_0;
           
            EnterCriticalSection(&accura);
                printf("*** Elettore%d *** prende la matita,ed entra nella cabina%d\n",num,pos);
            LeaveCriticalSection(&accura);

            Sleep(GetRandom(10000,15000));

       

        EnterCriticalSection(&accura);
            Mutex_Matita_occupata[pos] = 1; //indica che la matita non è più in possesso dell'elettore
            printf("*** Elettore%d *** ha finito di votare,va a mare...\n",num);
        LeaveCriticalSection(&accura);

      conta_schede++;
    }
}
//----------------------------------------------------------------------------------------------------------------
// Procedura che determina la fine del programma...
//----------------------------------------------------------------------------------------------------------------
HANDLE Finito(LPDWORD lpdwParam)
{
    int *fine;
    fine=(int*)lpdwParam;
    getch();
    *fine=1;

    return 0;
}

Torna a Lab Sistemi Operativi

There are 3 comments on this page. [Visualizza commenti]

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