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
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 ]
