pthread赋值输出错误

时间:2013-11-27 14:25:23

标签: c++ pthreads

我的作业有问题:

我在xyz空间中有一个10000点的数组坐标A和一个中心为0.5,0.5,0.5且每边有1个长度的起始立方体。 该立方体包含所有10k点 然后立方体将分成8个相同的较小立方体,每个立方体将包含10k点的较小部分。

因此主线程将产生8个线程,每个立方体一个,根据num_child找到每个立方体的中心(*参见下面的解释)并计算它包含的点数。 在每个线程中,我创建一个临时结构来进行计算,然后将结构推送到全局向量。

(*例如,中心位于0.5,0.5的2d框将分为4:a(0.25,0.25),b(0.75,0.25),c(0.75,0.25),b(0.75,0.75))< / p>

当我运行程序时,我得到的输出是“10000 240 240 240 240 240 240 240 240”,这是错误的。如果我在gdb中运行程序并逐步执行代码,结果是正确的。

可能出现什么问题?如果您需要对代码的任何部分进行更多说明,请告诉我......

感谢您的时间

PS:你需要-std = c ++ 11 -pthread标志来编译。我知道C ++ 11有内置线程,但是赋值的重点是在pthreads中完成。

更新:我在代码中做了一些戳,我发现所有的盒子都有相同的中心(0.75,0.75,0.75)。我还在gdb上的“case 0”中设置了一个断点,但它永远不会中断

#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;}

2 个答案:

答案 0 :(得分:0)

可能不会解决你的问题,但是如果我没弄错的话,你在running_threads等待它成为0的时候就不能正确地控制竞争条件。我会按照

pthread_mutex_lock
while (running_threads>0){
  pthread_cond_wait
}
pthread_mutex_unlock

然后让线程在pthread_cond_signal

之后调用running_threads--;

答案 1 :(得分:0)

您将相同的结构传递给所有线程函数 如果你运气不好,你将在上一次迭代的线程开始之前在一次迭代中修改其成员。