2017-05-18 81 views
0

更新包含的代碼C:輸出前multithreading-父線程退出

第一塊我是新來的多線程和我有輸出各個線程的結果在C程序的問題之後。具體來說,我試圖將一個整數數組中的平均值,最大值和最小值輸出給用戶,每個用戶使用不同的線程。但是,應該打印三個值的父線程在其子線程完成時終止。

爲了測試起見,我當前在子線程中打印結果,但我需要在父線程中打印這些值。代碼如下:

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


void *avgThread(int *nums,int*out) 
{ 
    //sleep(1); 
    int total = 0,x,avg; 
    for(x=0;x<7;x++) total+=nums[x]; 
    avg = total/7; 
    *out = avg; 
    printf("%d\n",avg); 
} 

void *minThread(int *nums,int*out) 
{ 
    int min = nums[0],x; 
    for(x=1;x<7;x++) if(nums[x]<min) min=nums[x]; 
    *out = min; 
    printf("%d\n",min); 

} 

void *maxThread(int *nums,int*out) 
{ 
    int max = nums[0],x; 
    for(x=1;x<7;x++) if(nums[x]>max) max=nums[x]; 
    *out = max; 
    printf("%d\n",max); 

} 

void *parentThread(int*nums) 
{ 
    int average,minimum,maximum; 
    pthread_t avg,min,max; 
    pthread_attr_t avgfun,minfun,maxfun; 

    pthread_attr_init(&avgfun); 
    pthread_attr_init(&minfun); 
    pthread_attr_init(&maxfun); 

    pthread_create(&avg, &avgfun, avgThread(nums,&average), NULL); 
    pthread_create(&min, &minfun, minThread(nums,&minimum), NULL); 
    pthread_create(&max, &maxfun, maxThread(nums,&maximum), NULL); 

    pthread_join(avg, NULL); 
    pthread_join(min, NULL); 
    pthread_join(max, NULL); 

    printf("%d\n",maximum); 
    printf("%d\n",average); 
    printf("%d\n",minimum); 
    pthread_join(pthread_self(),NULL); 

    return NULL; 
} 

int main() 
{ 
    int nums[] = {90, 81, 78, 95, 79, 72, 85}; 
    pthread_t prnt; 
    pthread_attr_t parent; 
    pthread_attr_init(&parent); 
    pthread_create(&prnt,&parent,parentThread(nums),NULL); 
    pthread_join(prnt,NULL); 
    sleep(3); 

    exit(0); 
} 

更新

謝謝帕維爾和其他人指出一些事情我做錯了。我已經對線程初始化和調用進行了必要的修改。我也能夠在父線程中輸出計算的平均值,最大值和最小值,但只能通過使所述變量在範圍內爲全局。如果有人可以告訴我,如果我可以保留:

int average,maximum,minimum 

inside * parentThread並仍然計算它們內部的子線程,這將是偉大的。這裏是我現在的代碼:

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

int average,minimum,maximum; 

void *avgThread(void *numsptr) 
{ 
    sleep(1); 
    int *nums=(int*)numsptr; 

    int total = 0,x; 
    for(x=0;x<7;x++) total+=(int)nums[x]; 
    average = total/7; 
    return NULL; 
} 

void *minThread(void *numsptr) 
{ 
    sleep(2); 
    int *nums=(int*)numsptr,x; 
    minimum = nums[0]; 
    for(x=1;x<7;x++) if((int)nums[x]<minimum) minimum=(int)nums[x]; 
    return NULL; 
} 

void *maxThread(void *numsptr) 
{ 
    sleep(3); 
    int *nums=(int*)numsptr,x; 

    maximum = nums[0]; 
    for(x=1;x<7;x++) if((int)nums[x]>maximum) maximum=(int)nums[x]; 
    return NULL; 
} 

void *parentThread(void *numsptr){ 
    int *nums=(int*)numsptr; 
    //int average,minimum,maximum; 
    pthread_t avg,min,max; 
    pthread_attr_t avgfun,minfun,maxfun; 

    pthread_attr_init(&avgfun); 
    pthread_attr_init(&minfun); 
    pthread_attr_init(&maxfun); 

    pthread_create(&avg, &avgfun, &avgThread,(void*)nums); 
    pthread_create(&min, &minfun, &minThread,(void*)nums); 
    pthread_create(&max, &maxfun, &maxThread,(void*)nums); 

    pthread_join(avg, NULL); 
    printf("The average value is %d\n",average); 
    pthread_join(min, NULL); 
    printf("The minimum value is %d\n",minimum); 
    pthread_join(max, NULL); 
    printf("The max value is %d\n",maximum); 

    return NULL; 
} 

int main() 
{ 
    int nums[] = {90, 81, 78, 95, 79, 72, 85}; 
    pthread_t prnt; 
    pthread_attr_t parent; 
    pthread_attr_init(&parent); 
    pthread_create(&prnt,&parent,&parentThread,(void*)nums); 
    pthread_join(prnt,NULL); 

    exit(0); 
} 
+0

關於'在pthread_join(pthread_self(),NULL);',阻塞自己的線程,直到它完成似乎並不像一個好的戰術決定。坦率地說,我不知道會發生什麼。我希望得到一個錯誤消息,但我不會因爲鎖定而感到驚訝。 – user4581301

+0

'pthread_create(&prnt,&parent,parentThread(nums),NULL);'以及對'pthread_create()'的其他調用表明您對如何將函數指針和參數傳遞給線程有嚴重的誤解。它應該是'pthread_create(&prnt,&parent,parentThread,nums)'。對於其他的你需要創建一個'struct',因爲你只能傳遞一個指針作爲參數。 –

+0

你的線程函數不返回承諾的'void *'。這是[Undefined Behavior。](http://en.cppreference.com/w/cpp/language/ub)。很難預測該計劃將做什麼。 – user4581301

回答

2

您不能正確啓動線程。你必須通過功能,將執行,但你實際上是調用你的函數和返回值傳遞給pthread_create

// call parentThread(nums) and then create thread. 
pthread_create(&prnt, &parent, parentThread(nums),NULL); 

你想要做的是這樣的:

void *parentThread(void *nums_ptr) 
{ 
    int *nums = (int*)nums_ptr; 
    ... 
    return NULL; 
} 

int main() 
{ 
    int nums[] = {90, 81, 78, 95, 79, 72, 85}; 
    pthread_t prnt; 
    pthread_create(&prnt, NULL, &parentThread, (void*)nums); 
    ... 
} 

同樣適用於所有你的其他線程。 其他問題你有:

  • 你的線程函數(即pthreads期望)應該採取一個空指針並返回void指針。例如:void *threadFunc(void *nums)
  • 你的函數返回的東西(如return NULL;
  • 你不應該試圖聯合自己的線程:pthread_join(pthread_self(),NULL);

如果有人能告訴我,如果我能保持:int average,maximum,minimum inside * parentThread並且仍然在子線程內計算它們

當然你可以做到這一點。定義一些struct,用於存儲所有這些數據,並通過指針指向的數據到你的主題:

struct myState 
{ 
    int average, minimum, maximum; 
    int *nums 
}; 

void *avgThread(void *data) 
{ 
    sleep(1); 
    myState *state = (myState*)data; 

    int total = 0,x; 
    for(int x=0; x<7; x++) 
     total += state->nums[x]; 
    state->average = total/7; 
    return NULL; 
} 

void *parentThread(void *nums_ptr) 
{ 
    int *nums = (int*)nums_ptr; 
    myState state; 
    state.nums = nums; 
    ... 
    pthread_create(&avg, &avgfun, &avgThread, &state); 
    ... 
    pthread_join(avg, NULL); 
    printf("The average value is %d\n", state.average); 
    ... 
    return NULL; 
}