2011-11-05 175 views
5

我是韓國人,我不擅長英語,但如果你給我評價那裏
我會很高興,並會嘗試去理解它。pthread(分割錯誤)

我創建了例如10個線程,並在創建後嘗試加入它們並返回值。
但是,當我加入最後一個線程時,出現了分段錯誤。

結果出來這樣的..

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) 

當我創建4個線程就好像

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) 

我似乎無法找到原因。

#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

我不能重現這一點,我試過2和4線程。它的工作非常好,即使在Valgrind中也是如此。你能告訴我們關於這個問題的其他事嗎? – VolatileDream

+1

您是否嘗試過調試器? gdb是你的朋友。 – vanza

+1

歡迎來到SO。 :-) – 2012-01-11 00:36:54

回答

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

你只分配空間,這裏有兩個要素,因此,如果您推出超過2個線程,你會跑出數組的結尾,並可能崩潰或損壞堆棧。

此外:

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

statusint,而不是一個void *;嘗試這將嘗試在int中存儲void *。在許多64位平臺上,這也會溢出(因爲void *將是8字節,而int是4)。使status a void *,並停止試圖擺脫這樣的編譯器錯誤。他們是有原因的錯誤。

+0

當我啓動2個以上的線程時,我改變了這些數字。 – IKS

+0

好點,但我們仍然無法解釋2線程上的段錯誤。 – VolatileDream

+0

@IKS,那麼您必須在代碼中顯示更改這些數字的位置,這完全可能導致您忘記更改數字。更好的方法是,開始使用'#define's或變量來定義要啓動的線程數量,並且使用這個變量/宏來設置循環和數組分配,以防止出現不一致。 – bdonlan