Сводка от очень полезной статьи, которую Джаганнатх связал , и комментарии к возможному использованию.
Существует 3 политики запуска:
any
: библиотека выбирает, создавать поток или нет
async
: вы явно просите создать поток
deferred
: вы явно просите создать поток , а не
Таким образом, политика deferred
- это способ получения детерминированной ленивой оценки (также называемой вызовом по необходимости). Например, предположим, что у вас есть:
void MyClass::lazy(std::future<int> const& f) {
if (this->notReady()) { return; }
if (this->stillNotReady()) { return; }
if (this->value() == 42) { return; }
this->go(f.get());
}
Теперь, если вычисление значения этого целого числа равно long (например, оно может вызвать обратную передачу по сети), то вычислять его во всех случаях, в которых оно действительно не требуется, является расточительным. .. и теперь у нас есть инструмент для этого!
void func(MyClass& mc) {
std::future<int> f = std::async(std::launch::deferred, []() {
return stoi(memcached.get("KEY"));
});
mc.lazy(f);
}
Обратите внимание, что немного отличается от использования std::function<int()>
(и замыкания), потому что вычисление выполняется один раз и для всех , гарантируя, что последующие вызовы будут всегда вернуть тот же результат.
Разница с другими политиками также может быть выражена в том, выполняется ли операция , когда вам не нужно значение .
any
: может выполняться в другом потоке (проактивно) или не выполняться вообще
async
: будет выполняться в другом потоке
deferred
: будет не выполнено
Следовательно, deferred
дает вам лучший контроль, что важно, если вызов имеет побочный эффект.