다중 스레드 C ++ 11 프로그램에서 예외가 처리되지 않으면 어떻게됩니까?
두 개의 스레드를 실행하는 C ++ 11 프로그램이 있는데 그 중 하나가 처리되지 않은 예외를 발생 시키면 어떻게됩니까? 전체 프로그램이 맹렬한 죽음을 맞이할까요? 예외가 발생하는 스레드가 혼자 죽습니까 (그렇다면이 경우 예외를 얻을 수 있습니까)? 완전히 다른 것?
실제로 변경된 것은 없습니다. n3290의 표현은 다음과 같습니다.
일치하는 핸들러가 없으면 함수
std::terminate()
가 호출됩니다.
의 동작은 terminate
로 사용자 정의 할 수 set_terminate
있지만 다음 과 같습니다.
필수 동작 : A
terminate_handler
는 호출자에게 반환하지 않고 프로그램 실행을 종료합니다.
따라서 이러한 경우 프로그램이 종료되고 다른 스레드는 계속 실행할 수 없습니다.
예외 전파에 대한 정당한 관심이있는 것 같고 이것은 적어도 질문과 약간 관련이 있기 때문에 여기에 내 제안 std::thread
이 있습니다. 예를 들어 더 높은 수준의 추상화를 구축하는 데 안전하지 않은 기본 요소로 간주되는 것입니다. 그들은있어 이중 위험 예외 현명한 : 예외가 우리가 시작 스레드 내부 꺼질 경우 우리가 보여준 바와 같이, 모든, 불면. 그러나 시작된 스레드에서 예외가 발생하면 의 소멸자가 조인 또는 분리 (또는 동등하게 스레드가 아님)를 요구 std::thread
하기 때문에 잠재적으로 문제가 발생할 수 있습니다 . 이러한 요구 사항을 위반하면 ... !std::thread
*this
std::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
'Programing' 카테고리의 다른 글
GWT 모듈을 REDUX로 (재) 컴파일해야 할 수 있습니다. (0) | 2020.12.09 |
---|---|
Lion에서 PostgreSQL 서버가 종료되지 않음 (Mac OS 10.7) (0) | 2020.12.09 |
Java의 toLowerCase () 및 toUpperCase ()와 함께 로케일 사용 (0) | 2020.12.09 |
Java에서 문자열이 가비지 수집되는 경우 (0) | 2020.12.09 |
git rm-치명적 : 경로 사양이 파일과 일치하지 않음 (0) | 2020.12.09 |