Обратите внимание, что ваш первоначальный пример генерирует не две задачи, а четыре, поскольку каждый из двух потоков 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). задачи).