Какой самый эффективный способ выбраться из parallel_for?
Чтобы выйти из стандартного цикла for, мы делаем следующее:
for(int i = 0; i < 100; i+)
{
bool bValue = DoSomething();
//Break if bValue is true
if(bValue)
break;
}
Я провел некоторое исследование и нашел некоторую информацию о Отмена в PPL
и я рассматриваю 3 варианта
-Целевая группа
// To enable cancelation, call parallel_for in a task group.
structured_task_group tg;
task_group_status status = tg.run_and_wait([&]
{
parallel_for(0, 100, [&](int i)
{
bool bValue = DoSomething();
if (bValue)
{
tg.cancel();
}
});
});
-Бросить исключение
try
{
parallel_for(0, 100, [&](int i)
{
bool bValue = DoSomething();
if (bValue)
throw i;
});
}
catch (int n)
{
wcout << L"Caught " << n << endl;
}
-Используйте логическое значение
// Create a Boolean flag to coordinate cancelation.
bool bCanceled = false;
parallel_for(0, 100, [&](int i)
{
// Perform work if the task is not canceled.
if (!bCanceled)
{
bool bValue = DoSomething();
if (bValue)
bCanceled = true;
}
});
structured_task_group
вариант является единственным, который на самом деле будет разумным. № 3 просто небезопасен, а № 2 — просто ужасное злоупотребление исключениями.
Начиная с Visual Studio 2012, существует run_with_cancellation_token
функция, которая будет выполнять лямбду вместе с cancellation_token
, Внутри лямбды,
Ссылка на сайт: Функция run_with_cancellation_token
Пример кода можно найти на MSDN по адресу: Как: использовать отмену для выхода из параллельного цикла
Я не могу говорить за «эффективность» этого подхода, так как подозреваю, что в его реализации задействовано исключение C ++. Однако этот код может быть проще, чем другие подходы, и он позволяет использовать большинство конструкций PPL, не ограничиваясь structured_task_group
,