2017-05-31 17 views
10

w którym nić nazywa się obsługi przypadku:W jakim wątku jest wywoływana operacja zakończenia?

  1. gdy wyjątek jest wewnątrz noexcept funkcji?

  2. , gdy użytkownik dzwoni pod numer std::terminate()?

  3. przy uruchomieniu lub zniszczeniu thread?

Czy jest zdefiniowany w standardzie, czy będę miał dostęp do obiektów thread_local?

+1

Mój zdrowy rozsądek podpowiada mi, że zostanie wywołany w wątku, który nazwał 'std :: terminate'? Uważam, że Standard nie zajmuje się tym wyraźnie. – DeiDei

+0

Wierzę, że to nieokreślone zachowanie (lub może być niezdefiniowane?) –

+0

Powiedziałbym, że w wątku, który faktycznie ustawił program obsługi, idk –

Odpowiedz

2

Ten Podsumowując odpowiedź Odpowiedzi udzielone w komentarzach i odpowiedź już usunięte:

  • To nie jest określony w normie (DeiDei, Sprawdziłem też w N4618)

  • Niemniej , z przyczyn technicznych jest mało prawdopodobne, że program obsługi jest wywoływany w innym wątku, niż ten, który wywołał wywołanie: std::terminate (Galik, Hans Passant)

  • Zostało to zweryfikowane na kompilatorze online (Rinat Veliakhmedov), obsługa zakończeń jest wywoływana w wątku, który powoduje wywołanie zakończenia.

można go przetestować sobie z tym kodem z usuniętym odpowiedź:

#include <string> 
#include <exception> 
#include <iostream> 
#include <thread> 
#include <mutex> 

std::mutex mutex; 
const auto& id = std::this_thread::get_id; 
const auto print = [](std::string t){ 
    std::lock_guard<std::mutex> lock(mutex); 
    std::cout << id() << " " << t << std::endl; 
}; 

void my_terminate_handler(){ 
    print("terminate"); 
    std::abort(); 
} 

void throwNoThrow() noexcept { throw std::exception(); } 
void terminator()   { std::terminate();  } 

int main() { 
    std::set_terminate(my_terminate_handler); 
    print("main");  
#ifdef CASE1 
    auto x1 = std::thread(throwNoThrow); 
#elif CASE2 
    auto x1 = std::thread(terminator); 
#elif CASE3  
    auto x1 = std::thread(throwNoThrow); 
#endif 
    x1.join(); 
} 

Zawarcie jest nieokreślona, ​​ale wydaje się, że program obsługi jest zawsze być nazywane w wątku, który powoduje std::terminate do Zostać wezwanym. (testowane na gcc-5.4, gcc-7.1, clang-3.8 z pthreads)