Из encppreference.com
:
Если
std::future
, полученный изstd::async
, не перемещается из ссылки или не привязывается к ссылке, деструкторstd::future
будет блокироваться в конце полного выражения до тех пор, пока не завершится асинхронная операция, по существу сделав код, такой как следующий синхронный:blockquote>std::async(std::launch::async, []{ f(); }); // temporary's dtor waits for f() std::async(std::launch::async, []{ g(); }); // does not start until f() completes
Если бы я понял это правильно, это происходит из эти части стандарта (N4527):
§30.6.6 [futures.unique_future]:
~future();
Эффекты:
- освобождает любое общее состояние (30.6.4);
blockquote>§30.6.4 # 5 [futures.state] (выделение мое):
Когда говорят, что асинхронный возвращаемый объект или асинхронный провайдер освобождают его общее состояние, это означает:
[...] .
- эти действия не будут блокировать для состояния общего состояния, чтобы быть готовым, за исключением того, что он может блокироваться, если все следующие являются истинными: общее состояние было создано вызовом std :: async, общее состояние - n ot еще не готов, и это была последняя ссылка на общее состояние.
blockquote>Поскольку вы не сохранили результат своего первого вызова
std::async
, деструкторstd::future
вызывается и поскольку все 3 условия выполнены:
std::future
был создан черезstd::async
;- общее состояние еще не готово (из-за вашего бесконечного цикла);
- нет никакой ссылки на это будущее
... тогда вызов блокируется.