← Назад ко всем вопросам

Что такое exception_ptr

1️⃣ Как кратко ответить

std::exception_ptr — это тип, определенный в стандартной библиотеке C++, который используется для хранения и передачи информации об исключениях между потоками. Он позволяет захватывать текущее исключение и повторно выбрасывать его в другом контексте, что полезно для обработки исключений в многопоточных приложениях.

2️⃣ Подробное объяснение темы

std::exception_ptr — это часть стандартной библиотеки C++, введенная в C++11, которая предоставляет механизм для захвата и передачи исключений между различными частями программы, особенно в многопоточных приложениях. Это позволяет более гибко и безопасно обрабатывать исключения, возникающие в одном потоке, в другом потоке.

Зачем это нужно

В многопоточных приложениях часто возникает необходимость обрабатывать исключения, которые были выброшены в одном потоке, в другом потоке. Например, если поток выполняет какую-то задачу и выбрасывает исключение, основной поток может захотеть обработать это исключение. std::exception_ptr позволяет сохранить информацию об исключении и передать ее между потоками.

Как это работает

std::exception_ptr работает в связке с двумя основными функциями: std::current_exception() и std::rethrow_exception().

  • std::current_exception() захватывает текущее активное исключение и возвращает std::exception_ptr, который можно сохранить и передать.
  • std::rethrow_exception() используется для повторного выбрасывания исключения, сохраненного в std::exception_ptr.

Пример использования

Рассмотрим пример, где поток выполняет задачу и выбрасывает исключение, а основной поток обрабатывает это исключение.

#include <iostream>
#include <thread>
#include <exception>
​
// Глобальная переменная для хранения указателя на исключение
std::exception_ptr globalExceptionPtr = nullptr;
​
// Функция, выполняемая в потоке
void threadFunction() {
    try {
        // Генерируем исключение
        throw std::runtime_error("Ошибка в потоке");
    } catch (...) {
        // Захватываем текущее исключение и сохраняем его в глобальной переменной
        globalExceptionPtr = std::current_exception();
    }
}
​
int main() {
    // Создаем и запускаем поток
    std::thread t(threadFunction);
    t.join(); // Ожидаем завершения потока
​
    // Проверяем, было ли захвачено исключение
    if (globalExceptionPtr) {
        try {
            // Повторно выбрасываем исключение
            std::rethrow_exception(globalExceptionPtr);
        } catch (const std::exception& e) {
            // Обрабатываем исключение
            std::cout << "Поймано исключение: " << e.what() << std::endl;
        }
    }
​
    return 0;
}

Пояснение кода

  • Глобальная переменная globalExceptionPtr: используется для хранения указателя на исключение, чтобы его можно было передать между потоками.

  • Функция threadFunction: выполняется в отдельном потоке. Внутри блока try выбрасывается исключение std::runtime_error. В блоке catch используется std::current_exception() для захвата текущего исключения и сохранения его в globalExceptionPtr.

  • Основной поток: создает и запускает поток, затем ожидает его завершения с помощью join(). После завершения потока проверяется, было ли захвачено исключение. Если да, то оно повторно выбрасывается с помощью std::rethrow_exception(), и обрабатывается в блоке catch.

Этот механизм позволяет безопасно передавать и обрабатывать исключения между потоками, что делает std::exception_ptr важным инструментом в разработке многопоточных приложений на C++.

Тема: Исключения / noexcept / Safety
Стадия: Tech

🔒 Подпишись на бусти автора и стань Алигатором, чтобы получить полный доступ к функционалу сайта и отслеживать свой прогресс!

Твои заметки