Демонстрационный код:
#include <exception>
#include <future>
#include <iostream>
#include <stdexcept>
#include <thread>
void func1() {
std::cout << "Hello func1\n";
throw std::runtime_error("func1 error");
}
int main() {
try {
std::future<void> result1 = std::async(func1);
result1.get();
} catch (const std::exception &e) {
std::cerr << "Error caught: " <<e.what() << std::endl;
}
}
Выход:
Привет func1
Обнаружена ошибка: ошибка func1
Кажется, что основная функция может перехватывать исключение из потока. Но, исходя из этого вопроса и ответа, основная функция не должна иметь возможность перехватывать исключение потока. Это смутило меня. Возможно, я неправильно понимаю какую-то информацию. Может ли кто-нибудь дать несколько советов? Заранее спасибо.
std::future::get
: «Если исключение было сохранено в общем состоянии, на которое ссылается будущее (например, через вызов std::promise::set_exception()), то это исключение будет сгенерировано».И, std::thread
: Возвращаемое значение функции верхнего уровня игнорируется, и если она завершается выдачей исключения, вызывается std::terminate , std::async
: , если функция f возвращает значение или выдает исключение, он хранится в общем состоянии, доступном через std::future, которое async возвращает вызывающей стороне.
Во-первых, std::async
и std::thread
совсем не одно и то же. Более того, std::async
не требуется выполнять вызываемый объект в другом потоке, это зависит от политики запуска, которую вы использовали.
Я бы посоветовал вам прочитать документацию о std::async.
Но в любом случае любое выброшенное исключение уже обрабатывается std::async
и сохраняется в общем состоянии, доступном через возвращаемое std::future
, что означает, что исключения, если таковые имеются, повторно выбрасываются при вызове std::future<T>::get()
(что происходит в основном потоке в вашем случае) .
Вы не перехватываете исключения из
thread
, вы перехватываете их изasync
. Это две разные вещи, которые работают по-разному.