Страницы

Поиск по вопросам

понедельник, 1 апреля 2019 г.

Как правильно обработать исключение в нескольких потоках?

Можно ли запускать потоки внутри try{}? И что делать, когда посылается исключение? Ждать завершения других потоков? Есть ли в std::thread механизм для останова всех потоков, ну или конкретные инструменты для решения подобной проблемы? Или всё вручную придется делать? try{ // стартуют потоки }catch(std::exception исключение) { std::cout << "..."; }
поток1 { // при вызове ведет к неопределенному поведению. // может выполнится может нет throw std::exception(строка); }
поток2 { throw std::exception(строка); } А как мне в главный поток отрапортовать? о том что произошло исключение в потоке1? Глобальными переменными? try { // стартуют потоки поток1; поток2;
// здесь вечный цикл while(true) { ... основной поток };
}catch(std::exception исключение) { std::cout << "..."; }
поток1 { try{ .. throw std::exception(строка); .. } catch(std::exception исключение) {
} }
поток2 { try{ .. throw std::exception(строка); .. } catch(std::exception исключение) { }
}


Ответ

Вы не должны смотреть на исключения, как на проблему, с которой нужно "бороться". Исключения -- ваш друг. Это сигнал об ошибке, которую вы должны обработать. Функцию, реализующую логику потока, можно обернуть в try/catch, если это соответствует вашим целям. Можно ловить ошибки и в других местах. Заметьте, что try/catch вокруг запуска потоков не ловит исключения, случившиеся в потоке. Вам нужно завести try/catch в самой главной функции потока. (Спасибо @avp, который подметил это.) По поводу того, что делать, когда произошло исключение в потоке, ответ такой же, как и на вопрос, что делать если вообще произошло исключение. Вы должны поймать исключение, определить, что за ошибка произошла, и отреагировать соответственно этому. Общего рецепта нету и быть не может. Может быть, надо послать центральной логике программы сигнал о том, что программу надо немедленно завершить. Может быть, надо вывести запись в лог и повторить последнюю операцию. Может быть, надо проинформировать пользователя, и переспросить правильные параметры. Может быть, ошибку можно игнорировать. Останавливать другие потоки за вас никто не сможет, да и неправильно это -- вдруг поток держит lock или находится в середине критической операции? Если надо, остановите потоки самостоятельно. Заметьте, остановка остальных потоков в ответ на исключение очень редко бывает правильным решением.

Комментариев нет:

Отправить комментарий