2017-06-02 51 views
0

返回不正確的值與pthreads玩的時候我遇到了一個問題,當我測試的子線程之間的在pthread_join()。我試圖避免共享變量,所以我用另一個thread_create()函數來執行真實在pthread_create()在pthread_join(c)中

爲了跟蹤線程,我創建了一個pthread_t數組tid [N]來存儲線程,並且索引也會根據數組中的索引附加到每個線程。

但是,輸出示出了一些螺紋具有相同的索引。 我想變量索引必須以某種方式共享。索引被轉移爲實際參數到thread_create()和結構變量輸入假定的thread_create()函數完成之後被清除。我不太明白爲什麼索引會在子線程之間共享。 有沒有人可以解釋這一點?提前致謝!!

總之

問題1:爲什麼返回值是不正確的?

問題2:怎樣主線程等待其他線程完成(我不知道,所以我用了一段時間(1),以確保所有的線程完成。)

?一個註釋:如果我們取消註釋第38行中的睡眠(),程序會給出正確的輸出。

以下均代碼:

1 #include <stdio.h> 
    2 #include <stdlib.h> 
    3 #include <pthread.h> 
    4 #include <syscall.h> 
    5 
    6 #define N 4 
    7 
    8 typedef struct{ 
    9 
10   int index; 
11   pthread_t *tid; 
12 
13 }mix; 
14 
15 void* thread_talk(mix* input) 
16 { 
17   int* ret; 
18   int index = input->index; 
19   printf("In process %d, thread %u running, my index is %d\n", 
20    getpid(), pthread_self(), index); 
21    
22   /*thread 0 won't join*/ 
23   if(input->index == 0){ 
24     printf("thread 0 will stop\n"); 
25     return (void*)0; 
26   } 
27   /*Join the thread based on the index of tid*/ 
28   pthread_join(input->tid[index - 1], &ret); 
29   printf("My index is %d, I receive the return value %d\n",index, ret); 
30   return (void*)(input->index); 
31 } 
32 
33 int thread_create(pthread_t* tid, int index) 
34 { 
35   mix input = {index, tid}; 
36   printf("my index is %d\n"); 
37   pthread_create(&tid[index], NULL, thread_talk, (void*)(&input)); 
38   //sleep(1); 
39   return 0; 
40 } 
41 
42 int main() 
43 { 
44 
45   pthread_t  tid[N]; 
46   int    i; 
47   for(i = 0; i < N; i++) 
48     thread_create(tid,i); 
49   while(1);  
50   return 0; 
51 } 
+2

''中混合thread_create' input'超出範圍的函數返回後,但線程仍在訪問它。 – mch

+0

'thread_talk'中的'input-> tid [index-1]'是錯誤的,它應該只是'input-> tid'。 – zwol

+0

'(void *)(&input)'在線程獲得'input'的地址時,input已經*>不見了*。 – ThingyWotsit

回答

3

我試圖避免共享變量,所以我用另一個thread_create()函數來執行真實pthread_create()

...因此,您似乎已經爲自己創造了更糟糕的問題。至少,我理解你的意圖,以避免共享變量的指針傳遞每個線程thread_create()的局部變量input實現,但正如評論已經指出,該指針便具有thread_create()回報無效,啓動後立即新的線程。當線程解除引用這些指針時 - 它們會多次執行 - 會產生未定義的行爲。

問題1:爲什麼返回值不正確?

程序的行爲是不確定的,所以返回值可能不可靠的是你想要的或期望的,但對於判斷它們是否正確沒有基礎。

問題2:如何做的主要工作線程等待其他線程完成(我不知道,所以我用了一段時間(1),以確保所有的線程完成?)

一個線程等待另一個線程完成的方法是調用pthread_join()。由於你的每個線程都加入了前一個線程(或者至少嘗試這樣做),所以你只需要主線程加入最後一個線程。事實上,你不能讓兩個不同的線程同時嘗試加入同一個線程,所以最後一個線程是主線程應該嘗試加入的唯一線程。


殺青undefinedness:

  1. 擺脫thread_create()。它只是混淆了這個問題。

  2. 你有兩個選擇:

    1. 在主線程創建多個mix對象 - 例如他們的數組 - 並交給每個線程不同的一個。
    2. 在主線程中使用一個mix對象,將其傳遞給每個子對象,並讓子線程創建內部副本。此替代方法需要主線程和子線程之間的同步,以便主線程在新子進行復制之前不會繼續。

我會去與陣列,因爲它更容易正確地執行:

// ... 

int main() { 
    pthread_t  tid[N]; 
    mix    input[N]; 
    int    i; 

    for (i = 0; i < N; i++) { 
     input[i].index = i; 
     input[i].tid = tid; 
     pthread_create(&tid[index], NULL, thread_talk, (void*)(input + i)); 
    } 

    pthread_join(tid[N - 1], NULL); 

    return 0; 
}