我的作业有问题:
我在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;}
答案 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)
您将相同的结构传递给所有线程函数 如果你运气不好,你将在上一次迭代的线程开始之前在一次迭代中修改其成员。