многопоточность — код возврата программы C ++ при вызове std :: terminate в потоке

У меня есть программа, которая создает, который использует std::thread объекты для выполнения работы одновременно. Я вызываю программу из скрипта bash и хочу остановить скрипт, если программа не завершается с EXIT_SUCCESS, Я столкнулся с довольно неинтуитивным поведением в следующей ситуации: один из потоков выдает исключение (таким образом вызывая std::terminate), что приводит к завершению программы. Тем не менее, код возврата программы EXIT_SUCCESS (вместо некоторого кода ошибки, который я бы ожидал). Это почему?

Я знаю что используя std::thread это не умная идея во многих случаях, и я планирую перейти к std::async (или тому подобное), но на данный момент я заинтересован в быстром решении этого.

-1

Решение

Ну, считай меня глупым. Программа корректно возвращает код ошибки, но, как я передал вывод (он пишет много журнала) в teeкод возврата хранится в $? вероятно, один из tee, который выходит без сбоев.

[ПРАВКА] Я использую PIPESTATUS Теперь, чтобы получить правильный код выхода.

1

Другие решения

Как отметил Ричард Криттен в комментарии std::terminate() звонки std::abort(), но это не все.

C ++ предлагает довольно много механизмов для контроля таких ситуаций. Я могу предложить следующее:

Зарегистрируйте свой собственный обработчик для вызовов std::terminate() с использованием std::set_terminate():

#include <iostream>
#include <cstdlib>
#include <exception>

int main()
{
std::set_terminate
( []()
{
std::cout << "Unhandled exception\n";
std::exit(EXIT_FAILURE);
}
);

throw 1;
}

призвание std::exit() вызывает нормальное завершение программы с некоторыми шагами очистки.

Другой альтернативой будет регистрация SIGABORT обработчик и выйдите из программы с желаемым кодом выхода. Но в этом случае очистка ресурсов не производится.

1

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

#include <iostream>
#include<thread>
#include<exception>
#include<stdexcept>

static std::exception_ptr eptr = nullptr;

void foo()
{
try
{
....
throw std::runtime_error("Bla bla"); // put your exception instead of runtime_error
}
catch(...)
{
eptr = std::current_exception();
}
}

int main(int argc, char **argv)
{
std::thread t(foo);
t.join();

if (eptr)
{
try
{
std::rethrow_exception(eptr);
}
catch(const std::exception &ex)
{
std::cerr << "Thread exited: " << ex.what() << "\n";
return EXIT_FAILURE;

}
}

return EXIT_SUCCESS;
}

Этот метод гарантирует, что программа выйдет со статусом EXIT_FAILURE если поток выдает исключение.

0
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector