Как сообщить другому потоку про брошенный exception
1️⃣ Как кратко ответить
Для передачи исключения между потоками в C++ можно использовать std::promise и std::future. Поток, в котором возникает исключение, устанавливает его в std::promise, а другой поток получает его через связанный std::future и обрабатывает.
2️⃣ Подробное объяснение темы
В многопоточных приложениях на C++ часто возникает необходимость передавать информацию об исключениях между потоками. Это важно для корректной обработки ошибок и предотвращения некорректного завершения программы. Для этого в C++ можно использовать механизмы std::promise и std::future.
Зачем это нужно
Когда в одном потоке возникает исключение, оно не может быть автоматически передано в другой поток. Если не обработать исключение, это может привести к завершению потока и, возможно, всей программы. Поэтому важно иметь механизм для передачи информации об исключении в другой поток, который может его обработать.
Как это работает
std::promise и std::future — это стандартные инструменты C++ для асинхронного программирования. std::promise позволяет установить значение или исключение, которое будет доступно через связанный std::future. std::future предоставляет интерфейс для получения этого значения или исключения.
Пример кода
#include <iostream>
#include <thread>
#include <future>
#include <stdexcept>
// Функция, выполняемая в отдельном потоке
void threadFunction(std::promise<int>& prom) {
try {
// Имитация работы, которая может вызвать исключение
throw std::runtime_error("Exception in thread");
} catch (...) {
// Устанавливаем исключение в promise
prom.set_exception(std::current_exception());
}
}
int main() {
// Создаем promise и получаем связанный с ним future
std::promise<int> prom;
std::future<int> fut = prom.get_future();
// Запускаем поток, передавая в него promise
std::thread t(threadFunction, std::ref(prom));
try {
// Ожидаем результат из future
int result = fut.get();
} catch (const std::exception& e) {
// Обрабатываем исключение, переданное из потока
std::cout << "Caught exception: " << e.what() << std::endl;
}
// Ожидаем завершения потока
t.join();
return 0;
}
Пояснение кода
-
Создание
std::promiseиstd::future:std::promise<int> prom;— создается объектstd::promise, который будет использоваться для передачи исключения.std::future<int> fut = prom.get_future();— создаетсяstd::future, связанный сstd::promise, который будет использоваться для получения результата или исключения.
-
Запуск потока:
std::thread t(threadFunction, std::ref(prom));— запускается новый поток, которому передается ссылка наstd::promise.
-
Обработка исключения в потоке:
- Внутри
threadFunctionпроисходит попытка выполнения кода, который может вызвать исключение. - Если исключение возникает, оно перехватывается и устанавливается в
std::promiseс помощьюprom.set_exception(std::current_exception());.
- Внутри
-
Получение и обработка исключения в основном потоке:
int result = fut.get();— основной поток ожидает результат изstd::future. Если вstd::promiseбыло установлено исключение, оно будет выброшено здесь.- Исключение перехватывается и обрабатывается в блоке
catch, выводя сообщение об ошибке.
-
Завершение потока:
t.join();— основной поток ожидает завершения работы потока, чтобы корректно завершить программу.
Использование std::promise и std::future позволяет безопасно и эффективно передавать исключения между потоками, обеспечивая надежную обработку ошибок в многопоточных приложениях.
🔒 Подпишись на бусти автора и стань Алигатором, чтобы получить полный доступ к функционалу сайта и отслеживать свой прогресс!
Подписаться