我有以下代码:
int working_threads=1;
#pragma omp parallel
{
int my_num=omp_get_thread_num()+1;
int idle=false;
while(working_threads>0) {
if(my_num==1)
working_threads=0;
#pragma omp barrier
}
}如果我运行它,它不时挂在屏障上。线程越多,这种情况就越有可能发生。我试着用printf调试它,似乎有时并不是所有的线程都被执行,因此屏障将永远等待它们。这种情况发生在第一次迭代中,显然第二次迭代永远不会运行。
这是一段无效的代码吗?如果是的话,我怎样才能改变它呢?我需要并行运行一个while循环。以前不知道将执行多少个循环,但是可以保证所有线程都有相同的迭代次数。
发布于 2017-05-16 13:10:41
尽管您试图与屏障同步,但在working_threads上确实存在一个竞赛条件,很容易导致不相等的迭代量:
thread 0 | thread 1
... | ...
while (working_threads > 0) [==true] | ...
if (my_num == 1) [==true] | ...
working_threads = 0 | ...
| while (working_threads > 0) [==false]
[hangs waiting for barrier] | [hangs trying to exit from parallel]要修复特定的代码,还必须在while条件检查和working_threads = 0之间添加一个屏障。
#pragma omp parallel
{
int my_num=omp_get_thread_num()+1;
int idle=false;
while(working_threads>0) {
#pragma omp barrier
if(my_num==1)
working_threads=0;
#pragma omp barrier
}
}请注意,代码并不是最惯用或最优雅的解决方案。根据您的具体工作分担问题,可能有更好的方法。另外,您必须确保worker_threads只由单个线程编写--或者在编写时使用atomics。
https://stackoverflow.com/questions/44002149
复制相似问题