2013-06-01 52 views
0

我在學習C線程概念,並且我寫了簡單的下面的代碼。現在,當我編譯並運行它時,會出現意想不到的隨機行爲。帶睡眠C中的線程化

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

void * func_threadName(void * i) { 

    int *x=(int *)i; 
    printf("I'm thread : %d\n",*x); 

return NULL; 
} 
main() 
{ 
    int iter; 
    printf("testing multithreading....\n"); 

    pthread_t thread_arr[3]; 

    for (iter=0;iter<3;iter++) 
    { 
     pthread_create(&thread_arr[iter],NULL,func_threadName,&iter); 

    } 

    for (iter=0;iter<3;iter++) 
    { 
     pthread_join(thread_arr[iter],NULL); 
    } 
} 

它打印出不可預測的一樣:

[email protected]:~/Documents/my_C_codes$ ./thread_test.o 
testing multithreading.... 
I'm thread : 0 
I'm thread : 0 
I'm thread : 0 
[email protected]:~/Documents/my_C_codes$ ./thread_test.o 
testing multithreading.... 
I'm thread : 0 
I'm thread : 2 
I'm thread : 1 
[email protected]:~/Documents/my_C_codes$ ./thread_test.o 
testing multithreading.... 
I'm thread : 2 
I'm thread : 2 
I'm thread : 0 

但是,當我做出這樣有輕微的變化創建線程後,它完美的作品,並打印順序。

pthread_create(&thread_arr[iter],NULL,func_threadName,&iter); 
     sleep(1); 

現在的輸出是這樣的,每次:

[email protected]:~/Documents/my_C_codes$ ./thread_test.o 
testing multithreading.... 
I'm thread : 0 
I'm thread : 1 
I'm thread : 2 
[email protected]:~/Documents/my_C_codes$ ./thread_test.o 
testing multithreading.... 
I'm thread : 0 
I'm thread : 1 
I'm thread : 2 
[email protected]:~/Documents/my_C_codes$ ./thread_test.o 
testing multithreading.... 
I'm thread : 0 
I'm thread : 1 
I'm thread : 2 

我想了解的是,在第一種情況下,是顯示,因爲所有的線程一個線程之前共享相同的存儲空間,因此不可預知的行爲終止,其他使用相同的值我?歡迎任何其他信息。

回答

4

當線程正在運行時,您無法確切地知道,因此主線程可能會繼續並因此更改其循環中的計數器。由於循環計數器是一個指針,所有線程都有相同的指針指向完全​​相同的變量。您也可以在第二個循環中使用相同的變量,因此在線程的生命週期中可以修改兩次。

會更好(雖然比較「的hackish」)來傳遞數字「原樣」:

pthread_create(&thread_arr[iter], NULL, func_threadName, (void *) iter); 

然後在線程函數得到它,像這樣:

int x = (int) i; 
+1

-1不,它不是更好,它更糟糕。爲什麼黑客可以簡單地聲明一個數組來保存這些值?壞。 –

0

每個線程應該會看到不同的int對象,因此您必須使用第二個數組來管理該對象。

void * func_threadName(void * i) { 

    int *x= i; 
    printf("I'm thread : %d\n",*x); 

    return NULL; 
} 

int main(void) { 
    printf("testing multithreading....\n"); 

    pthread_t thread_arr[3]; 
    int iter_id[3]; 

    for (int iter=0; iter<3; iter++) { 
    iter_id[iter] = iter; 
    pthread_create(&thread_arr[iter], NULL, func_threadName, &iter_id[iter]); 
    } 

    for (iter=0;iter<3;iter++) { 
    pthread_join(thread_arr[iter],NULL); 
    } 
} 

也是用C

  • 你不必鑄有一個返回類型的void*將其分配給另一個數據 指針
  • 所有功能時,即使main必須聲明
  • 一個不接收參數的函數應該用(void)
0

代碼的問題是您傳遞變量的地址而不是值。因此,所有線程都指向該地址存儲的「相同」值。這意味着,正如約阿希姆所說的那樣,價值可能不會變得足夠快,以致於新創建的線程得到它。當使用'sleep'時,主線程允許處理器執行其他指令,因此在創建新線程之前更改迭代變量的值。最後,你需要傳遞變量的值而不是像Joachim例子中的地址。