#cpp #многопоточность #исключения
Можно ли запускать потоки внутри 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 исключение) { } }
Ответы
Ответ 1
Вы не должны смотреть на исключения, как на проблему, с которой нужно "бороться". Исключения -- ваш друг. Это сигнал об ошибке, которую вы должны обработать. Функцию, реализующую логику потока, можно обернуть в try/catch, если это соответствует вашим целям. Можно ловить ошибки и в других местах. Заметьте, что try/catch вокруг запуска потоков не ловит исключения, случившиеся в потоке. Вам нужно завести try/catch в самой главной функции потока. (Спасибо @avp, который подметил это.) По поводу того, что делать, когда произошло исключение в потоке, ответ такой же, как и на вопрос, что делать если вообще произошло исключение. Вы должны поймать исключение, определить, что за ошибка произошла, и отреагировать соответственно этому. Общего рецепта нету и быть не может. Может быть, надо послать центральной логике программы сигнал о том, что программу надо немедленно завершить. Может быть, надо вывести запись в лог и повторить последнюю операцию. Может быть, надо проинформировать пользователя, и переспросить правильные параметры. Может быть, ошибку можно игнорировать. Останавливать другие потоки за вас никто не сможет, да и неправильно это -- вдруг поток держит lock или находится в середине критической операции? Если надо, остановите потоки самостоятельно. Заметьте, остановка остальных потоков в ответ на исключение очень редко бывает правильным решением.Ответ 2
1) да, но это обработает только проблемы запуска, но не самого потока 2) обрабатывать. Но по месту, в нужном потоке. Каждый поток продолжит исполнение. 3) Поток должен останавливать себя сам.Ответ 3
Можно, но исключения выкинутые из потока в месте вызова не поймаются. Это просто невозможно т.к. начиная с точки создания код выполняется параллельно. Если исключение выйдет за границы первичной функции потока, вызовется std::terminate (Cтандарт 15.5.1, 30.3.1.2/4). Зависит от задачи и от политики обработки ошибок. Можно аварийно завершаться (действие по умолчанию), можно например сделать обертку над потоком, который ловит все не отловленные исключения и сигнализирует о них упрощенный пример. Или же есть замечательные std::future, std::packaged_task, std::async пример
Комментариев нет:
Отправить комментарий