Выбор ответа Senior Многопоточность и модель памяти обновлено

Ловушка std::async

Вопрос

Почему вызов std::async(std::launch::async, work); без сохранения результата выполняется синхронно?

Попробуйте сами

Выберите вариант, и откроется разбор.

Показать ответ и разбор

Коротко

Правильный ответ: Деструктор временного future от std::async ждёт завершения задачи. Future, полученный от std::async, особый: его деструктор блокируется до завершения задачи.

Варианты ответа

  1. std::async всегда синхронный, параллелизм даёт только std::thread
  2. Деструктор временного future от std::async ждёт завершения задачиправильный ответ
  3. Политика launch::async запускает задачу в текущем потоке вызова
  4. Компилятор оптимизирует неиспользуемый future и вызывает work напрямую

Разбор

Future, полученный от std::async, особый: его деструктор блокируется до завершения задачи. Если результат не сохранить, временный объект умрёт сразу и превратит асинхронный вызов в синхронный. Ещё одна ловушка: политика по умолчанию async | deferred позволяет отложить запуск до get().

  • С сохранённым future задача действительно идёт параллельно.
  • launch::async гарантирует запуск в новом потоке (как если бы).
  • Это не оптимизация, а поведение деструктора.

Ответьте сами, а не прочитайте

В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.