PDA

View Full Version : [C] errore che non riesco a trovare - thread


gepeppe
28-05-2008, 14:24
salve, in questo semplice programma, c'è un errore (infatti il programma mi va in segmentation fault, ma non riesco proprio a trovarlo!!

Questo è il testo dell'esercizio:
-scrivere un programma che prende da riga di comando un intero n, imposta un estore per il segnale SIGUSR1 e poi crea n thread
-ciascun thread aspetta un numero casuale di secondi tra 1 e 5, poi invia il segnale SIGUSR1 a uno a caso tra i suoi fratelli thread (e poi ripete il procedimento)
● il gestore del segnale stampa a video il tid del thread corrente e il numero totale di segnali SIGUSR1 ricevuti da quel thread fino a quel momento


L'esercizio teoricamente l'ho risolto, ma non riesco a capire il motivo di questo errore. Ecco il mio programma:


pthread_key_t key=0;

void foo(int x)
{
int *n;

if(x==SIGUSR1)
{
void *p = pthread_getspecific(key);

n = (int *)p;
*n=*n+1;
printf("il thread %u ed n.segnali = %d\n", (int)pthread_self(), *n);
}
}

void *func(void *x)
{
pthread_setspecific(key, malloc(5*sizeof(int)));

while(1)
{
sleep(1+ rand() % 5);
kill(getpid(), SIGUSR1);
}

}
int main(int argc, char *argv[])
{
int n, i, err;

n=atoi(argv[1]);

pthread_t tid[n];

signal(SIGUSR1, foo);

pthread_key_create(&key, NULL);

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

printf("aspetto la terminazione\n");
for(i=0; i<n; i++)
pthread_join(tid[i], NULL);

return 0;
}

vizzz
28-05-2008, 15:45
prova a fare qualche controllo sui puntatori (che non siano null)

es:

void *p = pthread_getspecific(key);
if (p == NULL)
{
printf("errore");
return;
}

gepeppe
28-05-2008, 15:54
si..esce spesso errore...a volte anche da subito...ma come mai??

è la getspecific che fallisce....ma perchè?

sottovento
29-05-2008, 08:29
si..esce spesso errore...a volte anche da subito...ma come mai??

è la getspecific che fallisce....ma perchè?

Dovresti controllare sempre l'esito delle operazioni che fai, altrimenti pecchi di "fede cieca" (blind trust).
Per esempio, controlla la malloc() e tutte le chiamate che ti possono produrre errore.
Comunque mi sembra che prepari un'area di memoria mediante la malloc() e poi non la inizializzi. Non so cosa leggerai da li'.
Inoltre nella risposta al signal, non controlli se hai letto un'area valida oppure hai letto NULL. E' importante farlo, visto che la chiave e' comunque creata a NULL.