Я создаю несколько std :: threads, которые будут отсоединены. Я бы хотел, чтобы они работали в течение долгого времени и хотели бы, чтобы они сами обрабатывали исключения.
Я создаю поток, используя std :: thread (Function) и вызываю detach перед выпуском мьютекса и где функция выполняет следующие действия:
void BlockStart() noexcept {
std::lock_guard<std::mutex> sync(lock);
}
void Function()
{
BlockStart();
try
{
throw;
}
catch(...)
{
std::cerr << "Caught something...\n";
}
}
Каждый раз, когда я запускаю этот код, обработчик исключений не вызывается. Вызывается обработчик по умолчанию std :: terminate(), который вызывает прерывание.
Как получить поток std :: thread, который обрабатывал исключения?
На основании ответа на этот вопрос: qaru.site/questions/129300/...
Если вы сделаете
throw;
сам по себе, и для него не существует текущего исключения, а затем программа резко завершается. (Более конкретно,terminate()
вызывается.)
Вы можете сделать что-то вроде
void Function()
{
try
{
SomeOtherFunction();
}
catch(...)
{
std::cerr << "Caught something...\n";
}
}
Также обратите внимание, что защита блокировки + мьютекс внутри функции BlockStart()
будет блокироваться только в пределах продолжительности функции и не будет сохраняться после ее возвращения. Решение заключалось бы в том, чтобы замок блокировки блокировки находился внутри Function()
void Function() {
std::lock_guard<std::mutex> sync(lock);
...
Вызов throw
сам перебрасывает текущее исключение, но это работает только при вызове внутри блока catch
. Если вы попытаетесь вызвать throw
самостоятельно внутри блока try
когда нет текущего исключения, вызывается terminate()
и ваше приложение умирает. Вы должны сказать throw
ЧТО бросить, когда внутри блока try
, например:
void Function()
{
BlockStart();
try
{
throw std::runtime_error("something bad happened");
}
catch(const std::exception& e)
{
std::cerr << "Caught something... " << e.what() << std::endl;
}
}
Кроме того, использование std::lock_guard
внутри BlockStart()
бесполезно. sync
- локальная переменная, поэтому она выходит из области действия и освобождает мьютекс, когда BlockStart()
завершает работу. Имеет смысл использовать его, если он действительно что-то делает, пока мьютекс заблокирован, например:
void BlockStart() noexcept
{
std::lock_guard<std::mutex> sync(lock);
// do something here while the mutex is locked...
}