#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 пример
Комментариев нет:
Отправить комментарий