2014-12-02 28 views
0

我目前正在嘗試瞭解C中的多線程。但是,我得到了非常意想不到的結果,這些結果讓我難以置信。在這個程序中,我正在嘗試使用線程填充矩陣。我創建了1024個線程,將i值傳遞給函數。然後我繼續使用它。通過在多線程中傳遞int值的意外結果,C

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

#define SIZE 1024 

static double a[SIZE][SIZE]; 
static double b[SIZE][SIZE]; 
static double c[SIZE][SIZE]; 

void* 
init_matrix(void* msg) 
{ 
     int j; 
     int num = *((int*) msg); 
     printf("%d\n", num); 

     for (j = 0; j < SIZE; j++) { 
      a[num][j] = drand48(); 
      b[num][j] = drand48(); 
     } 

     pthread_exit(NULL); 
} 

int 
main(int argc, char **argv) 
{ 
     //Init threads 
     pthread_t p_initThreads[SIZE]; 

     int i,j; 
     for(i = 0; i< SIZE; i++)                               
     { 
       pthread_create(&p_initThreads[i], NULL, init_matrix, (void*)&i); 
     } 
     for(j = 0; j<SIZE; j++) 
     { 
       pthread_join(p_initThreads[j], NULL); 
     } 
} 

從prinf的預期結果是; 1-2-3-4-5-6-7-8-9-10。有可能的 由於它處於線程狀態而導致的結果。但是我電腦上的結果是這樣的;

1-2-2-4-5-7-24-25-25-25-25-25-25-25-25-25-25-25-25-25-25-25-25-25-25-26-35-36-36-37-37-37-37-37-37-37-37-38-39-40 

By commentout out;

for (j = 0; j < SIZE; j++) { 
      a[num][j] = drand48(); 
      b[num][j] = drand48(); 
     } 

我得到我想要的結果。這是爲什麼?它不應該做任何事情數量!

+0

所有線程的msg指針指向您在創建線程時在main()中修改的同一個變量。如果線程沒有立即開始並且在下一個循環傳入'main()'之前越過'int num = *((int *)msg)''行,'num'將不會獲得您的值期望 - 並且幾個線程可能會以相同(可能是錯誤的)值結束。 – Dmitri 2014-12-02 16:42:09

+0

您必須確保在另一個線程正在或可能正在修改它時沒有線程訪問對象。 (除非該對象是特別允許的類型) – 2014-12-02 16:57:43

回答

1

您正在傳遞i的地址作爲線程的輸入參數。如果你通過i的價值,你會得到1-2-3-4-5 -...。但是當你傳遞地址時,完全可能在執行printf行之前,主線程已經增加了i。並且printf顯示當前值i,而不是它在創建線程時的值。

+0

你完全正確。 Buuuuut ..是否甚至有可能做我想要做的事情? (通過一些類型轉換魔術?)或者我必須創建一個單獨的數組作爲緩衝區?然後傳遞該數組中的地址? – 413X 2014-12-02 16:58:35

+0

爲了'printf'的值,使用'(void *)i'而不是'(void *)&i'和'int num =(int)msg;'分配給'num'。 – 2014-12-02 17:05:50

0

你有一個race condition多線程訪問相同的內存位置(變量i),因爲您將地址i傳遞給所有線程。

你真正想要做的是通過i。調用pthread_create()有:

pthread_create(&p_initThreads[i], NULL, init_matrix, (void*)i); 

和讀取值:

int num = (int) msg; 

代替:int num = *((int*) msg);

您也應該檢查是否pthread_create()返回非零故障。如果是這樣的話,你不會得到預期的結果。