Programing

다중 스레드 C ++ 11 프로그램에서 예외가 처리되지 않으면 어떻게됩니까?

lottogame 2020. 12. 9. 07:42
반응형

다중 스레드 C ++ 11 프로그램에서 예외가 처리되지 않으면 어떻게됩니까?


두 개의 스레드를 실행하는 C ++ 11 프로그램이 있는데 그 중 하나가 처리되지 않은 예외를 발생 시키면 어떻게됩니까? 전체 프로그램이 맹렬한 죽음을 맞이할까요? 예외가 발생하는 스레드가 혼자 죽습니까 (그렇다면이 경우 예외를 얻을 수 있습니까)? 완전히 다른 것?


실제로 변경된 것은 없습니다. n3290의 표현은 다음과 같습니다.

일치하는 핸들러가 없으면 함수 std::terminate()가 호출됩니다.

의 동작은 terminate로 사용자 정의 할 수 set_terminate있지만 다음 같습니다.

필수 동작 : A terminate_handler는 호출자에게 반환하지 않고 프로그램 실행을 종료합니다.

따라서 이러한 경우 프로그램이 종료되고 다른 스레드는 계속 실행할 수 없습니다.


예외 전파에 대한 정당한 관심이있는 것 같고 이것은 적어도 질문과 약간 관련이 있기 때문에 여기에 내 제안 std::thread이 있습니다. 예를 들어 더 높은 수준의 추상화를 구축하는 데 안전하지 않은 기본 요소로 간주되는 것입니다. 그들은있어 이중 위험 예외 현명한 : 예외가 우리가 시작 스레드 내부 꺼질 경우 우리가 보여준 바와 같이, 모든, 불면. 그러나 시작된 스레드에서 예외가 발생하면 의 소멸자가 조인 또는 분리 (또는 동등하게 스레드가 아님)를 요구 std::thread하기 때문에 잠재적으로 문제가 발생할 수 있습니다 . 이러한 요구 사항을 위반하면 ... !std::thread*thisstd::terminate

위험에 대한 코드 맵 std::thread:

auto run = []
{
    // if an exception escapes here std::terminate is called
};
std::thread thread(run);

// notice that we do not detach the thread
// if an exception escapes here std::terminate is called

thread.join();
// end of scope

물론, 어떤 사람들 detach은 우리가 시작하는 모든 스레드를 단순히 편집 하면 그 두 번째 지점에서 안전 하다고 주장 할 수 있습니다 . 문제는 어떤 상황 join에서는 가장 현명한 일이라는 것입니다. 예를 들어 퀵 정렬의 '순진한'병렬화는 하위 작업이 끝날 때까지 기다려야합니다. 이러한 상황 join에서는 동기화 프리미티브 (접선 부) 역할을합니다.

운 좋게도 내가 언급 한 더 높은 수준의 추상화가 존재하며 표준 라이브러리와 함께 제공됩니다. 그들은있다 std::async, std::future뿐만 아니라 std::packaged_task, std::promise하고 std::exception_ptr. 위의 동등한 예외 안전 버전 :

auto run = []() -> T // T may be void as above
{
    // may throw
    return /* some T */;
};

auto launched = std::async(run);
// launched has type std::future<T>

// may throw here; nothing bad happens

// expression has type T and may throw
// will throw whatever was originally thrown in run
launched.get();

그리고 실제로 호출 get한 스레드를 호출 async하는 대신 벅을 다른 스레드로 전달할 수 있습니다.

// only one call to get allowed per std::future<T> so
// this replaces the previous call to get
auto handle = [](std::future<T> future)
{
    // get either the value returned by run
    // or the exception it threw
    future.get();
};

// std::future is move-only
std::async(handle, std::move(launched));
// we didn't name and use the return of std::async
// because we don't have to

참고URL : https://stackoverflow.com/questions/7272093/what-happens-when-an-exception-goes-unhandled-in-a-multithreaded-c11-program

반응형