2011-11-05 4 views
5

Jestem Koreańczykiem i nie jestem dobry w angielskim, ale jeśli dasz mi komentarz na dole, to
Będę bardzo zadowolony i spróbuję to zrozumieć.pthread (błąd segmentacji)

Utworzyłem na przykład 10 wątków i próbowałem połączyć je po utworzeniu i zwrócić wartość.
Ale kiedy przyłączam się do ostatniego wątku, otrzymuję błąd segmentacji.

Wynik wychodzi tak ..

Before Thread 1 create 
After Thread 1 create 
Before Thread 0 create 
After Thread 0 create 
Before Thread 1 join 
After Thread 1 join 
Before Thread 0 join 
Segmentation Fault(core dumped) 

gdy tworzę 4 wątki to jak

Before Thread 3 create 
After Thread 3 create 
Before Thread 2 create 
After Thread 2 create 
Before Thread 1 create 
After Thread 1 create 
Before Thread 0 create 
After Thread 0 create 
Before Thread 3 join 
After Thread 3 join 
Before Thread 2 join 
After Thread 2 join 
Before Thread 1 join 
After Thread 1 join 
Before Thread 0 join 
Segmentation Fault(core dumped) 

I nie wydaje się znaleźć dlaczego.

#include <stdio.h> 
#include <stdlib.h> 
#include <pthread.h> 
#include <unistd.h> 

pthread_mutex_t mutex_lock; 

struct arg_struct { 
     int a; 
     int b; 
}; 

void *t_function(void *data) { 
     pthread_mutex_lock(&mutex_lock); 

     struct arg_struct *arg = (struct arg_struct *)data; 
     long int s; 

     s = arg->a; 

     pthread_mutex_unlock(&mutex_lock); 

     return (void **)s; 
} 

int main() 
{ 
     int i; 

     pthread_t p_thread[2]; 
     int thr_id; 
     int status; 

     struct arg_struct arg[2]; 

     for(i = 1; i >= 0; i--) { 
       arg[i].a = i; 
       arg[i].b = i; 
     } 

     pthread_mutex_init(&mutex_lock, NULL); 

     for(i = 1; i >= 0; i--) { 
       printf("Before Thread %d create\n", i); 
       thr_id = pthread_create(&p_thread[i],NULL, t_function, (void *)&arg[i]); 
       printf("After Thread %d create\n", i); 
       usleep(1000); 
     } 

     int temp[2]; 

     for(i = 1; i >= 0; i--) { 
       printf("Before Thread %d join\n", i); 
       pthread_join(p_thread[i], (void**)&status); 
       printf("After Thread %d join\n", i); 
       temp[i] = status; 
     }i 

     printf("%d%d", temp[1], temp[0]); 

     pthread_mutex_destroy(&mutex_lock); 

     return 0; 
} 
+0

Nie mogę tego odtworzyć, próbowałem 2 i 4 wątków. Działa doskonale, nawet w Valgrind. Czy możesz nam powiedzieć coś jeszcze na temat problemu? – VolatileDream

+1

Czy próbowałeś debuggera? gdb to twój przyjaciel. – vanza

+1

Witamy w SO. :-) –

Odpowiedz

9
pthread_t p_thread[2]; 
    struct arg_struct arg[2]; 
    int temp[2]; 

Wystarczy tylko przydzielone miejsce dla dwóch elementów tutaj, więc jeśli uruchomić więcej niż 2 wątki będziesz uciekać się do końca tablicy i potencjalnie ulec awarii lub uszkodzony stos.

Dodatkowo:

  pthread_join(p_thread[i], (void**)&status); 

status jest int, nie void *; próba ta będzie próbować zapisać void * w int. Na wielu 64-bitowych platformach będzie to również powodować przepełnienie (ponieważ void * będzie miało 8 bajtów, a int będzie 4). Utwórz status a void * i przestań próbować odrzucać takie błędy kompilatora. To są błędy z jakiegoś powodu.

+0

kiedy uruchamiam więcej niż 2 wątki, zmieniłem te liczby. – IKS

+0

Dobrze, ale nadal nie potrafimy wyjaśnić uszkodzenia na 2 wątkach. – VolatileDream

+0

@IKS, będziesz musiał pokazać kod, w którym zmieniłeś te cyfry, jest to całkowicie możliwe, że zapomniałeś go zmienić. Co więcej, zacznij używać '# define's lub zmiennej, aby zdefiniować liczbę uruchomionych wątków i mieć zarówno pętle, jak i alokacje tablicy, używając tej zmiennej/makra, aby zapobiec niespójnościom. – bdonlan