我遇到的情况是,#pragma omp task
块中有两个#pragma omp parallel
。
第一个任务是等待5秒的简单工作。第二项任务是等待复杂的用户输入操作,难度更大。
bool timed_out=false;
#pragma omp parallel num_threads(2), shared(timed_out)
{
#pragma omp task
{
sleep(5);
#pragma omp atomic write
time_out=true;
}
#pragma omp task
{
// wait for user input
}
#pragma omp taskwait
}
基本上,我想在成功接收用户输入或击中5秒后发生什么,然后我想跳出#pragma omp parallel
部分并继续执行main。
我不认为我可以在等待任务后使用#pragma omp single
,因为如果收到用户输入,则接下来会发生的是产生两个工作线程。
答案 0 :(得分:3)
请注意,您的初始示例不会生成两个任务,而是四个,因为并行区域中的两个OpenMP线程中的每个线程都将遇到task
构造,因此创建了一个任务。您必须用task
或master
构造包装两个single
构造,以避免这种情况,并确保只有一个任务创建任务:
bool timed_out=false;
#pragma omp parallel num_threads(2), shared(timed_out)
{
#pragma omp master
{
#pragma omp task
{
sleep(5);
#pragma omp atomic write
time_out=true;
}
#pragma omp task
{
// wait for user input
}
#pragma omp taskwait
}
}
要终止正在等待的第二项任务,可以使用OpenMP取消:
bool timed_out=false;
#pragma omp parallel master num_threads(2), shared(timed_out)
{
#pragma omp taskgroup
{
#pragma omp task
{
sleep(5);
#pragma omp atomic write
time_out=true;
#pragma omp cancel taskgroup
}
#pragma omp task
{
while(true) {
#pragma omp taskyield
#pragma omp cancellation point taskgroup
}
}
#pragma omp taskwait
}
需要taskgroup
来定义应受cancel
构造影响的任务。一旦遇到cancellation point
构造,等待任务中的while
构造将终止cancel
循环。由于第二个任务正在等待,它包含一个taskyield
来引入任务调度点并允许OpenMP实现调度另一个任务(这对您的最小示例来说不是必需的,但对于具有以下内容的代码可能是有用的更多OpenMP任务)。