nntp2http.com
Posting
Suche
Optionen
Hilfe & Kontakt

Threads e mutua esclusione

Von: Alexandros (niente_spam@chiedetemela.it) [Profil]
Datum: 08.05.2008 19:42
Message-ID: <_XGUj.305144$%k.406636@twister2.libero.it>
Newsgroup: it.comp.os.linux.development
Ciao a tutti...
... vi sono mancato, vero ? :)

Vengo subito al dunque...

Studiando la sincronizzazione per i thread, il primo concetto che si
incontra è quello di mutua esclusione, che voi tutti conoscete...

Nel merito, ho fatto un esercizietto che prevede due "fasi".

La prima, quella base, è:
"Scrivere un programma che accetta un intero n da riga di comando
crea n thread e poi aspetta la loro terminazione.
Ciascun thread aspetta un numero di secondi casuale tra 1 e 10
poi incrementa una variabile globale intera ed infine ne stampa
il valore."

La seconda è:
"Eliminare dal programma la race condition"

La race condition è ovviamente relativa al fatto che gli n thread
"operano" in lettura e scrittura su una variabile globale, e quindi
potrebbero nascere delle "incongruenze".

Ora, sintetizzando le due "fasi", posto il codice:

/*variabile precedentemente affetta da race condition*/
/*int count = 0;*/

struct conta_protetto_da_mux {
int count;
pthread_mutex_t mux;

};
struct conta_protetto_da_mux *sp;

void *f (void *x);

int main (int argc, char *argv[]) {

int i, err, n;

/*allocazione della struttura di conteggio*/
/*senza verifiche sull'allocazione*/
sp=malloc (sizeof(int));

/*inizializzazione*/
sp->count=0;
pthread_mutex_init(&sp->mux, NULL);

if (argc != 2) {
printf("Uso: %s <numero thread>\n", argv[0]);
exit(1);
}

n = atoi(argv[1]);
pthread_t tid[n]; /*allocazione consentita dallo C99*/

for (i=0; i<n ;i++) {
if ((err=pthread_create(&tid[i], NULL, f, NULL)) != 0) {
printf("errore: %s\n", strerror(err));
exit(1);
}
}

for (i=0; i<n ;i++)
pthread_join(tid[i],NULL);
printf("\nFatto!\n");

return 0;

}/*END main*/

void *f (void *x) {
/*dormo casualmente*/
sleep(rand() % 10);

pthread_mutex_lock(&sp->mux); /*blocco o aspetto*/
sp->count++;
pthread_mutex_unlock(&sp->mux); /*rilascio*/

printf("\nCiao! %d", sp->count);
return NULL;
}

Il tutto funziona... o almeno all'evidenza funziona :)

Mi chiedo... e vi chiedo: ma se invece di usare una struttura creata
apposta per gestire il mutex, utilizzassi una semplice variabile mux ?

Ovvero così: pthread_mutex_t mux=PTHREAD_MUTEX_INITIALIZER ?

Dove andrebbe dichiarata (e inizializzata) tale mux?
Globalmente? O nella start function?

Io penso globalmente... e nel caso, poi farei:

void *f (void *x) {
sleep(rand() % 10);

pthread_mutex_lock(mux);
count++;
pthread_mutex_unlock(mux);

printf("\nCiao! %d", count);
return NULL;
}

Tutto questo l'ho provato, e sembra funzionare...
... l'unica cosa è come effettivamente accorgersi se si è in race, e
quale metodo preferire ?

P.S.: lo Stevens fa solo esempi con la struttura (e relativa allocazione
din) e con pthread_mutex_init() ...

[ Auf dieses Posting antworten ]