2013-11-27 44 views
0

我有一個分配一個問題:並行線程分配輸出誤差

我有一個數組座標A的在XYZ空間10000點,並與中心0.5,0.5,0.5起始立方體和每一側有1個長度。 立方體包含所有10k點 然後,立方體將分成8個相同的較小立方體,每個立方體將包含10k點的較小部分。

因此,主線程會產生8個線程,每個立方體一個,根據num_child(*參見下面的解釋)找到每個立方體的中心並計算它包含的點數。 在每個線程中,我創建一個臨時結構來執行計算,然後將結構推送到全局向量。 (*例如以0.5,0.5爲中心的二維框將分成4:a(0.25,0.25),b(0.75,0.25),c(0.75,0.25),b(0.75,0.75))。

當我運行該程序時,我得到的輸出是「10000 240 240 240 240 240 240 240 240」,這是錯誤的。如果我在gdb中運行該程序並逐步完成代碼,則結果是正確的。

任何可能出錯的地方?如果您需要在代碼的任何部分,更多的解釋,請告訴我...

謝謝您的時間

PS:您將需要-std = C++ 11個-pthread標誌進行編譯。我知道C++ 11具有內置線程,但分配的要點是在pthread中完成。

更新:我做了一些戳在代碼中,我發現所有的框都有相同的中心(0.75,0.75,0.75)。此外,我設定爲「0的情況下」在gdb斷點,但它從來沒有斷

#include <iostream> 
#include <random> 
#include <thread> 
#include <vector> 

#define N 10000 
#define S 20 

typedef struct Box{ 
    int level, child[8], n; 
    float center[3]; 
}Box; 

static double A[N][3]; //Coordinate array 
std::vector<Box> box; 

//initializing mutexes and a variable to hold the running threads 
int running_threads; 
pthread_mutex_t running_mutex = PTHREAD_MUTEX_INITIALIZER; 

//arguments structer 
struct arg_struct{; 
    int num_child,level; 
}; 


void *create_child(void *arguments){ 

    Box temp; 

    pthread_mutex_lock(&running_mutex); 
    arg_struct *args=(arg_struct*)arguments; 
    int num_child=args->num_child; 
    temp.level=args->level; 
    float akmi=1/pow(2,args->level); 
    pthread_mutex_unlock(&running_mutex); 

    float d=(0.5/pow(2,temp.level)); 

    switch (num_child){ 
    case 0: 
     temp.center[0]=0.5-d; 
     temp.center[1]=0.5-d; 
     temp.center[2]=0.5-d; 
     break; 
    case 1: 
     temp.center[0]=0.5+d; 
     temp.center[1]=0.5-d; 
     temp.center[2]=0.5-d; 
     break; 
    case 2: 
     temp.center[0]=0.5-d; 
     temp.center[1]=0.5+d; 
     temp.center[2]=0.5-d; 
     break; 
    case 3: 
     temp.center[0]=0.5+d; 
     temp.center[1]=0.5+d; 
     temp.center[2]=0.5-d; 
     break; 
    case 4: 
     temp.center[0]=0.5-d; 
     temp.center[1]=0.5-d; 
     temp.center[2]=0.5+d; 
     break; 
    case 5: 
     temp.center[0]=0.5+d; 
     temp.center[1]=0.5-d; 
     temp.center[2]=0.5+d; 
     break; 
    case 6: 
     temp.center[0]=0.5-d; 
     temp.center[1]=0.5+d; 
     temp.center[2]=0.5+d; 
     break; 
    case 7: 
     temp.center[0]=0.5+d; 
     temp.center[1]=0.5+d; 
     temp.center[2]=0.5+d; 
     break; 
    } 

    int number=0; 


    for(int i=0;i<N;i++){ 
     if ((A[i][0]>=(temp.center[0]-akmi/2)) && (A[i][0]<=(temp.center[0]+akmi/2))){ 
      if((A[i][1]>=temp.center[1]-akmi/2)&&(A[i][1]<=temp.center[1]+akmi/2)){ 
       if((A[i][2]>=temp.center[2]-akmi/2)&&(A[i][2]<=temp.center[2]+akmi/2)){ 
         number++; 
        } 
      } 
     } 
    } 


    pthread_mutex_lock(&running_mutex); 
    temp.n=number; 
    box.push_back(temp); 
    running_threads--; 
    pthread_mutex_unlock(&running_mutex); 

} 

int main(){ 
    //Generate random A array 
    const double pi = 3.14159265358979323846; 
    std::default_random_engine rnd; 
    std::uniform_real_distribution<double> dist(0.0, 1.0); 

    for(int i=0; i<N; i++) 
    { 
     double z = dist(rnd); 
     double t = (pi/2.0)*dist(rnd); 
     double r = sqrt(1.0-z*z); 

     A[i][0]=r*cos(t); 
     A[i][1]=r*sin(t); 
     A[i][2]=z; 
    } 
    std::cout<<"\nCoordinates array completed\n"; 
/////// 

    Box temp; 
    arg_struct *args=new arg_struct; 
    pthread_t threads[8]; 

    //Original Box 
    temp.level=0; 
    temp.n=N; 
    temp.center[0]=0.5; 
    temp.center[1]=0.5; 
    temp.center[2]=0.5; 
    box.push_back(temp); 

    //Starting threads 
    for (int i=0;i<8;i++){ 
     pthread_mutex_lock(&running_mutex); 
     args->level=1; 
     args->num_child=i; 
     running_threads++; 
     pthread_mutex_unlock(&running_mutex); 
     pthread_create(&threads[i],NULL,create_child,(void*)args); 
    } 

    while(running_threads>0){ 

    } 

    for (int i=0;i<9;i++){ 
     std::cout<<box[i].n<<"\n"; 
    } 

    return 0;} 

回答

0

也許不是要去解決您的問題,但如果我沒有記錯的等待,當你不running_threads控制比賽條件正確它變成0。我會沿着

pthread_mutex_lock 
while (running_threads>0){ 
    pthread_cond_wait 
} 
pthread_mutex_unlock 

線做一些事情,然後讓線程調用你傳遞相同結構的所有線程函數pthread_cond_signalrunning_threads--;

0


如果您不走運,您將在一次迭代中修改其成員,然後開始前一次迭代的線程。