#c #openmp
#c #openmp
Вопрос:
У меня ситуация, когда у меня есть два #pragma omp task
s внутри #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
after my taskwait, потому что, если пользовательский ввод получен, следующее, что произойдет, — это создание двух рабочих потоков.
Ответ №1:
Пожалуйста, обратите внимание, что ваш первоначальный пример генерирует не две задачи, а четыре, поскольку каждый из двух потоков OpenMP в параллельной области столкнется с task
конструкцией и, таким образом, создаст задачу. Вам нужно было бы обернуть две task
конструкции с master
single
помощью конструкции or, чтобы избежать этого и убедиться, что только одна задача создает задачи:
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
обнаружения конструкции. Поскольку вторая задача находится в режиме ожидания, она содержит a taskyield
, чтобы ввести точку планирования задачи и разрешить реализации OpenMP планировать другую задачу (это не требуется для вашего минимального примера, но может быть полезно для кода с большим количеством задач OpenMP).
Комментарии:
1. Я только что осознал, что поменял роли задач, но я предполагаю, что точка все еще встречается.