- Semafori in C: cosa sono, come
funzionano e la relazione con i mutex -
|
|||
COSA SERVE PER QUESTO TUTORIAL | |||
Download | Chiedi sul FORUM | Glossario | conoscenza del linguaggio C e delle nozioni base per l'utilizzo dei thread con pthread | ||
Il concetto di semaforo | |||
I SEMAFORI Cosa sono i semafori e come vanno utilizzati.
Per il multi-threading le librerie POSIX pthread offrono principalmente
due strumenti per la sincronizzazione: i semafori e i mutex. In questo
articolo ci occuperemo dei semafori per capire esattamente cosa sono e
in che caso possono servire. Esplicitiamo la metafora del semaforo. #include <unistd.h> #include <stdlib.h> #include <semaphore.h> #include <pthread.h> #include <stdio.h> #define MACCHINE 10 #define POSTIPISTA 5 #define MAX_WAIT 10 sem_t semaforo; // Restituisce il valore del semaforo int valoreSemaforo(void) { int valore = -1; sem_getvalue(&semaforo, &valore); return valore; } void *macchina(void *arg) { // Controlliamo il semaforo: // se è verde passiamo e ne decrementiamo il valore, // se è rosso attendiamo che diventi verde. printf("Macchina %d al semaforo, valore: %d\n", (int) arg, valoreSemaforo()); sem_wait(&semaforo); printf("Macchina %d passata al semaforo, valore: %d\n", (int) arg, valoreSemaforo()); // La macchina fa il proprio giro in una quantità di tempo casuale. sleep((rand() % MAX_WAIT)+1); // Esce dalla pista, incrementa il semaforo e sblocca // un altro thread, se ve ne sono in attesa. sem_post(&semaforo); printf("Macchina %d uscita dal circuito, valore: %d\n", (int) arg, valoreSemaforo()); return NULL; } int main(int argc, char *argv[]) { int c1; pthread_t macchine[MACCHINE]; // Inizializziamo il semaforo sui posti disponibili // in pista sem_init(&semaforo, 0, POSTIPISTA); // Facciamo entrare una macchina ogni secondo for(c1=0;c1<MACCHINE;c1++) { pthread_create(&macchine[c1], NULL, macchina, (void*) c1); sleep(1); } // Attendiamo la conclusione di tutti i thread for(c1=0;c1<MACCHINE;c1++) pthread_join(macchine[c1], NULL); return 0; }
REALIZZAZIONE DI UN MUTEX TRAMITE I SEMAFORI Nell'esempio precedente abbiamo in sostanza realizzato un mutex, la cui sezione critica è il giro in pista, ma che, al contrario dei normali mutex, permette ad un numero arbitrario di thread (nell'esempio 5) di accedere alla sezione critica. Se avessimo impostato POSTIPISTA su 1, avremmo avuto l'equivalente di un mutex: #include <semaphore.h> #include <pthread.h> #include <stdio.h> #define THREADCOUNT 50 sem_t mutex; int count; void *myThread(void *arg) { int c1; sem_wait(&mutex); // Inizio sezione critica // Nessun rischio di scritture incrociate for(c1=0;c1<100;c1++) count++; // Fine sezione critica sem_post(&mutex); return NULL; } int main(int argc, char *argv[]) { int c1; pthread_t thread[THREADCOUNT]; // Il semaforo deve essere inizializzato a 1 // perché si comporti come un mutex sem_init(&mutex, 0, 1); // Avviamo i thread for(c1=0;c1<THREADCOUNT;c1++) pthread_create(&thread[c1], NULL, myThread, NULL); // Attendiamo la conclusione di tutti i thread for(c1=0;c1<THREADCOUNT;c1++) pthread_join(thread[c1], NULL); printf("Totale: %d\n", count); return 0; } |
|||
<< INDIETRO | by VeNoM00 |