This shows you the differences between two versions of the page.
— |
it:informatica:posix:threads_esempio2 [2017/11/30 06:58] (current) zioskenz created |
||
---|---|---|---|
Line 1: | Line 1: | ||
+ | ====== Threads Esempio 2 ====== | ||
+ | **Concetti:**\\ | ||
+ | Esempio riguardante la sincronizzazione di thread. Dei votanti (threads) esprimono un voto, il main colleziona i voti e stampa i risultati della votazione. | ||
+ | **Testo:**\\ | ||
+ | Vedi commento ad inizio programma | ||
+ | |||
+ | **Soluzione:**\\ | ||
+ | <file C threads_esempio2.c> | ||
+ | /* | ||
+ | Realizzare un programma basato sui thread per la gestione di un'operazione di voto. | ||
+ | |||
+ | In particolare: | ||
+ | - Il programma dovrà generare un thread per ogni votante (N_VOTANTI rappresenta il numero di votanti) | ||
+ | - Ogni thread: | ||
+ | * Impiegherà un tempo casuale tra 1 e 5 secondi per eseguire l'operazione di voto | ||
+ | * Deciderà al 50% se votare o non votare | ||
+ | * Nel caso decida di votare, verrà casualmente votato uno tra gli N_CANDIDATI possibili candidati | ||
+ | - Il risultato del voto dovrà essere salvato in un vettore globale di interi con nome voto | ||
+ | - Il thread, una volta ultimato, dovrà restituire il valore 1 | ||
+ | * In caso decida di non votare il thread dovrà restituire il valore 0 | ||
+ | * Un esempio di codice di thread deputato ad eseguire la votazione è il seguente: | ||
+ | |||
+ | static void *th_voter (void *arg) | ||
+ | { | ||
+ | int thread_num; | ||
+ | thread_num = * (int *)arg; | ||
+ | |||
+ | // Attende da 1 a 5 secondi prima di votare | ||
+ | sleep(rand()%5+1); | ||
+ | | ||
+ | // Con una probabilità del 50% non viene eseguito il voto | ||
+ | if (rand()%2) { // Operazione di voto | ||
+ | | ||
+ | voto[thread_num] = rand()%N_CANDIDATI+1; // Espressione del voto | ||
+ | printf("THREAD: %d VOTO: %d\n", thread_num, voto[thread_num]); | ||
+ | | ||
+ | pthread_exit((void *)1); | ||
+ | }else{ // Voto non eseguito | ||
+ | printf("THREAD: %d NO VOTO\n", thread_num); | ||
+ | pthread_exit((void *)0); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | * Quando tutti gli N_VOTANTI hanno finito l'operazione di voto (i.e., sono state eseguite tutte le pthread_join) | ||
+ | il thread principale dovrà stampare una statistica sul numero di voti ottenuti dai vari candidati | ||
+ | |||
+ | */ | ||
+ | |||
+ | #include <stdio.h> | ||
+ | #include <stdlib.h> | ||
+ | #include <unistd.h> | ||
+ | #include "pthread.h" | ||
+ | |||
+ | #define N_VOTANTI 5 | ||
+ | #define N_CANDIDATI 3 | ||
+ | |||
+ | |||
+ | int voto[N_VOTANTI]; | ||
+ | |||
+ | |||
+ | static void *th_voter (void *arg) | ||
+ | { | ||
+ | int thread_num; | ||
+ | thread_num = * (int *)arg; | ||
+ | |||
+ | /* Attende da 1 a 5 secondi prima di votare */ | ||
+ | sleep(rand()%5+1); | ||
+ | | ||
+ | /* Con una probabilità del 50% non viene eseguito il voto */ | ||
+ | if (rand()%2) { /* Operazione di voto */ | ||
+ | | ||
+ | voto[thread_num] = rand()%N_CANDIDATI+1; /* Espressione del voto */ | ||
+ | printf("THREAD: %d VOTO: %d\n", thread_num, voto[thread_num]); | ||
+ | | ||
+ | pthread_exit((void *)1); | ||
+ | }else{ /* Voto non eseguito */ | ||
+ | printf("THREAD: %d NO VOTO\n", thread_num); | ||
+ | pthread_exit((void *)0); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | |||
+ | int main (void) | ||
+ | { | ||
+ | int retcode; | ||
+ | pthread_t th[N_VOTANTI]; | ||
+ | void *retval; | ||
+ | int th_parameters[N_VOTANTI]; | ||
+ | int i, j; | ||
+ | | ||
+ | printf("Inizio operazione di voto\n\n"); | ||
+ | for(i=0; i<N_VOTANTI; i++){ | ||
+ | th_parameters[i] = i; | ||
+ | retcode = pthread_create (&th[i], NULL, th_voter, (void *) &(th_parameters[i])); | ||
+ | if (retcode != 0) | ||
+ | fprintf (stderr, "pthread_create failed %d\n", retcode); | ||
+ | } | ||
+ | |||
+ | |||
+ | /* Attesa della terminazione di tutti i thread */ | ||
+ | for(i=0; i<N_VOTANTI; i++){ | ||
+ | retcode = pthread_join (th[i], &retval); | ||
+ | if (retcode != 0) | ||
+ | fprintf (stderr, "pthread_join failed %d\n", retcode); | ||
+ | if (retval==0) | ||
+ | voto[i] = -1; /* Inserisco -1 nel caso di assenza di voto */ | ||
+ | } | ||
+ | /* gcc 5-voters.c -lpthread */ | ||
+ | |||
+ | printf("\nFine operazione di voto:\n"); | ||
+ | for(i=0; i<N_CANDIDATI; i++) { | ||
+ | int n_voti = 0; | ||
+ | for(j=0; j<N_VOTANTI; j++) | ||
+ | if(voto[j]==i+1 && voto[j]!=-1) | ||
+ | n_voti++; | ||
+ | printf("CANDIDATO: %d --> VOTI: %d\n", i+1, n_voti); | ||
+ | } | ||
+ | |||
+ | return 0; | ||
+ | } | ||
+ | </file> | ||
+ | |||
+ | **Commenti:**\\ |