2010-04-05 59 views
1

我有這段代碼給我帶來麻煩。我知道所有的線程正在讀取相同的結構。但我不知道如何解決這個問題。pthread以獨特的struct作爲參數C

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

typedef struct { 
    int a,b; 
} s_param; 

void * 
threadfunc(void *parm) 
{ 
    s_param *param2 = parm; 
    printf("ID:%d and v:%d\n",param2->a,param2->b); 
    pthread_exit(NULL); 
} 

int main(int argc, char **argv) 
{ 
    pthread_t thread[3]; 
    int rc=0,i; 
    void * status; 

    for(i=0; i<3 ; ++i){ 
    s_param param; 
    param.b=10; 
    param.a=i; 
    rc = pthread_create(&thread[i], NULL, threadfunc, &param); // !!!! 
    if(rc){ 
     exit(1); 
    } 
    } 

    for(i=0; i<3 ; ++i){ 
    pthread_join(thread[i],&status); 
    } 
    return 0; 
} 

輸出:

ID:2 and v:10 
ID:2 and v:10 
ID:2 and v:10 

和我需要什麼:

ID:0 and v:10 
ID:1 and v:10 
ID:2 and v:10 

回答

5

的sparam的範圍在for循環是循環中的靜態。當您設置.a和.b時,您一次又一次地寫入相同的結構,並且所有三個線程都獲得了指向同一個單一結構的指針。

相反,你可以使它們的排列像這樣創建結構的三個獨立的情況下..

int main(int argc, char **argv) 
{ 
    pthread_t thread[3]; 
    s_param param[3]; 
    int rc=0,i; 
    void * status; 

    for(i=0; i<3 ; ++i){ 
    param[i].b=10; 
    param[i].a=i; 
    rc = pthread_create(&thread[i], NULL, threadfunc, &param[i]); // !!!! 
    if(rc){ 
     exit(1); 
    } 
    } 
... etc 

應該提及的是,像這樣的數組創建結構(和線程)僅因爲你明確地做了一個與主線程的join()。如果你沒有這樣做,你會被建議在主函數之外靜態分配結構體,或者從堆中malloc它們,因爲一旦入口線程退出主函數,包含數組的棧幀將變得無效,並且很快將以不可預知的方式被覆蓋。

2

param在您的main函數的執行過程中位於堆棧中的相同位置。每當你設置新的值時,他們就會消除舊的值,並且所有的threadfunc都在看內存中的同一個點。 malloc結構,或以其他方式從不同的存儲位置創建它們。 (另外,使用堆棧內存來處理跨線程數據結構令人擔憂;只要您在退出時設置它們的功能,內存就無效。)

2

param是一個局部變量。它在循環的大括號結束時超出了範圍。你需要malloc一個新的s_param與每個線程。

或更好的是,定義一個包含pthread_ts_param的結構,並將該類型用於thread[3]

typedef struct { 
    int a,b; 
    pthread_t t; 
} s_param; 

int main(int argc, char **argv) 
{ 
    s_param thread[3]; // declare threads + params together 
    int rc=0,i; 
    void * status; 

    for(i=0; i<3 ; ++i){ 
    s_param *param = &thread[i]; // no persistent data declared here 
    param->b=10; 
    param->a=i; 
    rc = pthread_create(&thread[i].t, NULL, threadfunc, &thread[i]); // !!!! 
    if(rc){ 
     exit(1); 
    } 
    } 
… 
+1

's_param * param = thread [i];'應該是's_param * param =&thread [i];' – 2010-04-05 02:04:08