Ответ
std::thread — это низкоуровневый примитив для создания и управления потоком. Он требует явного управления жизненным циклом потока (вызов join() или detach()).
std::async — это высокоуровневая абстракция для запуска асинхронных задач. Она возвращает std::future<T> и делегирует управление потоками стандартной библиотеке (используя внутренний пул потоков или создавая новый).
Ключевые различия:
-
Управление потоком:
std::threadсоздает поток немедленно.std::asyncможет отложить выполнение (ленивая политикаstd::launch::deferred) или запустить асинхронно (std::launch::async).
-
Возврат результата и обработка ошибок:
std::threadне предоставляет прямого способа получить результат работы функции. Для передачи данных или ошибок нужны дополнительные механизмы (например, общие переменные с синхронизацией).std::asyncинкапсулирует результат (или исключение) в объектstd::future. Исключение, выброшенное в асинхронной задаче, будет перевыброшено при вызовеfuture.get().
-
Производительность и ресурсы:
- Создание
std::thread— относительно дорогая операция. std::asyncможет использовать существующие потоки из внутреннего пула, что эффективнее для множества мелких задач.
- Создание
Пример:
// Пример с std::thread (нужно вручную передать результат)
int result;
std::thread t([&result]() { result = someHeavyCalculation(); });
t.join();
std::cout << result << std::endl;
// Пример с std::async (результат инкапсулирован)
auto future = std::async(std::launch::async, []() {
return someHeavyCalculation();
});
// ... делаем другую работу ...
std::cout << future.get() << std::endl; // Блокируется, пока результат не готов
Когда что использовать:
std::thread— когда нужен полный низкоуровневый контроль над потоком (например, привязка к конкретному ядру CPU, нестандартный стек).std::async— для большинства задач «запусти-и-забудь» с получением результата, так как это безопаснее и часто эффективнее.