我遇到了#pragma omp task一个#pragma omp parallel块内有两个s的情况
第一个任务是一个简单的工作,只需等待 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
}
Run Code Online (Sandbox Code Playgroud)
基本上,我希望在成功接收到用户输入或达到 5 秒超时后发生的情况,然后我想跳出该#pragma omp parallel部分并继续执行 main。
我不认为我可以#pragma omp single在 taskwait 之后使用,因为如果收到用户输入,接下来会发生的是两个工作线程的产生。
请注意,您的初始示例不会生成两个任务,而是生成四个任务,因为并行区域中的两个 OpenMP 线程中的每一个都会遇到task构造并因此创建一个任务。您必须task用masterorsingle构造包装这两个构造以避免这种情况并确保只有一个任务创建任务:
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
}
}
Run Code Online (Sandbox Code Playgroud)
对于等待的终止,第二个任务,可以使用 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
}
Run Code Online (Sandbox Code Playgroud)
在taskgroup需要定义应该由受影响的任务cancel结构。一旦遇到cancellation point构造,等待任务中的构造将终止while循环cancel。由于第二个任务是自旋等待,它包含一个taskyield以引入任务调度点并允许 OpenMP 实现调度另一个任务(这对于您的最小示例来说不需要,但对于具有更多 OpenMP 任务的代码可能有用)。