【问题标题】:C++ OpenMP exit while loop inside a parallel forC++ OpenMP 退出 while 循环内并行 for
【发布时间】:2013-05-08 08:45:37
【问题描述】:

我在 Windows 7 机器上使用 Visual Studio 2010 和 OpenMP。我编写了以下代码片段:

#pragma omp parallel for
for(int jj=0;jj<2;jj++){
MSG msg;
// do something in parallel for jj
int i_loopcounter = 0;
bool b_continue = true;
while(GetMessage(&msg, NULL, 0, 0)&&b_continue){
    TranslateMessage(&msg);
    DispatchMessage(&msg);
    i_loopcounter++;    
    if(i_loopcounter==50){
        b_continue = false;
        //abort(); <- ugly, since a window appears  
        //exit(0); <- rest of the code is not executed
        //break;  <- not allowed
        //goto end; <- not allowed
    }
}
end:;
// do some other stuff in parallel for jj
} //end of parallel for

我的问题是:

如果我使用 b_continue 变量,第一个达到中止条件的 while 循环会导致程序挂起(这是一个竞争条件,我没有看到吗?),结果程序确实不执行其余代码。

那么我怎样才能让它工作呢?

我已经尝试了breaking out of structured block in openmp 中建议的解决方案,但这并没有改变这种情况。

需要自毁的 while 循环来触发从硬件下载文件。完成后,程序应该对该文件做一些工作。在我开始并行化代码之前,使用 while 循环中的 break 语句运行良好。

感谢任何 cmets,它们给了我解决此问题的提示。

更新:我现在把代码改成了

int i_loopcounter = 0;
    while(_i_NoDownloads!=2){
        GetMessage(&msg, NULL, 0, 0);
        TranslateMessage(&msg);
        DispatchMessage(&msg);
        i_loopcounter++;    
        if(_b_control){
            cout<<i_loopcounter <<" of Thread "<<omp_get_thread_num()<<endl;
        }       
    }

全局变量_i_NoDownloads 计算下载文件的数量,如果达到 2 则不再需要消息循环。然而,即使进行了这种更改,程序的行为也不会改变,尽管 while 循环现在不一定要进行 50 次迭代。我认为问题在于同时破坏消息循环。

更新 2: 在阅读了大量有关 Windows 消息概念的信息后,我找到了一个可行的解决方案。并行部分没有完成的原因是 GetMessage 的行为。

再次,非常感谢任何为此问题做出贡献的人。

干杯 总而言之

【问题讨论】:

  • 在不同的 OpenMP 线程中运行相同的消息循环?我无法想象这会如何表现。消息循环只属于一个线程。你需要彻底重新设计你的代码。
  • 从显示 i_loopcounter 和 omp_get_thread_num() 的一些 cout 命令中,似乎有两个消息循环,因为我得到了两个线程号(0 和 1)

标签: c++ while-loop multiprocessing openmp nested-loops


【解决方案1】:

【讨论】:

  • 谢谢你的链接,但我最终得到的结果与问题描述中的相同。通常我不想中止并行区域。我想退出 while 循环,以便并行 for 可以完成,如果我没有为 while 循环设置中止条件,程序将永远不会终止。目前我正在考虑使用部分的解决方案。在这里,我将有三个线程,其中 2 个用于并行线程,它们向第三个线程发送消息,第三个线程处理它们并在一段时间后终止。但我不知道它是否有效。消息处理目前对我来说不是很清楚。
【解决方案2】:

您似乎使用了少量硬编码的迭代次数:

#pragma omp parallel for
for(int jj = 0; jj < 2; jj++){
 /* ... */
} //end of parallel for

您可能想探索基于sections 指令的解决方案:

#pragma omp parallel
{
#pragma omp sections
  {
#pragma omp section
    {
      /* jj = 0 */
    }         
#pragma omp section
    {
      /* jj = 1 */
    }             
  } // End sections
#pragma omp single
  { 
    /* While loop */
  }
  /* ... */      
} // End parallel

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-07-23
    • 1970-01-01
    • 1970-01-01
    • 2012-05-19
    • 1970-01-01
    • 2012-07-31
    • 2022-01-19
    相关资源
    最近更新 更多