5

我已经使用带有“pragma omp for”循环的 OpenMP,现在想尝试 OpenMP 任务。但是一个应该并行运行 2 个任务的简单程序似乎不起作用。我误解了任务的使用还是这里出了什么问题?

#include<iostream>
#include<omp.h>

//ubuntu 12.04 LTS, gcc 4.6.3
//g++ test_omp.cpp -fopenmp

int main()
{
 #pragma omp parallel
 {
  #pragma omp single
  {

      #pragma omp task
      {
          while(true) 
          {
           usleep(1e6);
           #pragma omp critical (c_out)
            std::cout<<"task1"<<std::endl;
          }
      }

      #pragma omp task
      {
          while(true) 
          {
           usleep(1e6);
           #pragma omp critical (c_out)
            std::cout<<"task2"<<std::endl;
          }
      }

  }
 }
}

输出为:task1 task1 task1 .....

所以第二个任务没有运行。

4

1 回答 1

3

从 OpenMP 规范:

当线程遇到任务构造时,会从相关结构化块的代码中生成任务。任务的数据环境是根据任务构造上的数据共享属性子句、每个数据环境 ICV 和任何适用的默认值创建的。

遇到的线程可以立即执行任务,或推迟执行。在后一种情况下,可以为团队中的任何线程分配任务。使用任务同步结构可以保证任务的完成。任务构造可以嵌套在外部任务中,但内部任务的任务区域不是外部任务的任务区域的一部分。

(强调我的)

我读这个的方式:一个线程开始执行你的single部分。它到达task指令,此时它可能决定要么运行任务本身,要么将其交给另一个线程。当它决定自己运行任务时会出现问题 - 它永远不会返回。

我不太确定为什么你的例子中有task/ single。你想要做的似乎是一个案例omp parallel sections

int main()
{
 #pragma omp parallel sections num_threads(2)
 {
      #pragma omp section
      {
          while(true)
          {
           usleep(3e5);
           #pragma omp critical (c_out)
            std::cout<<"task1"<<std::endl;
          }
      }
      #pragma omp section
      {
          while(true)
          {
           usleep(5e5);
           #pragma omp critical (c_out)
            std::cout<<"task2"<<std::endl;
          }
      }
 }
}
于 2013-10-07T10:59:49.190 回答