Ответ
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— для большинства задач «запусти-и-забудь» с получением результата, так как это безопаснее и часто эффективнее.
Ответ 18+ 🔞
Ёпта, ну смотри, тут история про потоки, как будто на дворе 2002-й год и мы только про concurrency узнали. Есть два чувака: std::thread и std::async. Первый — это как голый провод под напряжением, брать голыми руками — овердохуища мороки. Второй — как розетка с защитой от детей, вставил вилку и похуй.
std::thread — это низкоуровневый примитив, типа кувалды. Сам создал поток, сам им управляй, сам не забудь его либо прибить (join()), либо отпустить в свободное плавание (detach()), а то будет тебе хиросима и нигерсраки — программа упадёт, а ты будешь охуевать, почему.
std::async — это уже обёртка, интеллигент такой. Ты говоришь: «Эй, выполни эту хуйню асинхронно», а он тебе в ответ кидает std::future<T> — типа расписку, что результат будет. А сам уже решает, создавать новый поток или взять из какого-то внутреннего пула, тебе, в общем, доверия ебать ноль, но зато удобно.
В чём разница, если по-простому:
- Кто рулит: С
std::threadты сам, как заправский механик, крутишь гайки. Сstd::asyncты как пассажир в такси — сказал адрес и ждёшь, пока довезут, можешь по дороге спать. - Где результат: В
std::threadрезультат сам выкручивайся, как хочешь — через общие переменные, мьютексы, ещё какую мудню. Вstd::asyncвсё аккуратненько упаковано в этотfuture. Вызвалget()— и тебе вывалили результат. А если там в потоке исключение вылетело — так оно тебе прямо вget()и прилетит, не потеряется, ебать копать. - Сколько стоит: Создать новый
std::thread— это не хуй собачий, операция тяжёлая.std::asyncможет переиспользовать уже созданные потоки, что для кучи мелких задач — просто пизда рулю.
Смотри, как это выглядит в коде:
// Вот так с std::thread — старый добрый геморрой.
int result; // Общая переменная, волнение ебать.
std::thread t([&result]() { result = someHeavyCalculation(); }); // Запустили.
t.join(); // Обязательно ждём, а то поток убежит, а мы с пустым result останемся.
std::cout << result << std::endl;
// А вот так с std::async — цивилизация, блядь.
auto future = std::async(std::launch::async, []() {
return someHeavyCalculation(); // Просто возвращаем значение.
});
// ... а тут мы пока можем делать другую работу, пить кофе...
std::cout << future.get() << std::endl; // Достаём результат, когда надо.
Так когда что брать?
std::thread— когда ты реально знаешь, что делаешь, и тебе нужен тотальный контроль. Типа настроить размер стека или привязать поток к конкретному ядру процессора. Это для гиков, которые не бздят.std::async— для 95% всех остальных случаев. Запустил задачу, получилfuture, и живи спокойно. Безопаснее, проще, и часто ещё и быстрее выходит. Чувак, если сомневаешься — бериasync, не прогадаешь.