2017-05-31 18 views
10

Trong đó chủ đề được gọi là chấm dứt handler:Trong đó thread là trình xử lý chấm dứt được gọi là?

  1. khi một ngoại lệ được ném ra bên trong một hàm noexcept?

  2. khi người dùng gọi std::terminate()?

  3. khi khởi động hoặc hủy thread?

Được định nghĩa trong tiêu chuẩn, tôi có quyền truy cập vào các đối tượng thread_local không?

+1

Cảm giác chung của tôi cho tôi biết nó sẽ được gọi trên chuỗi được gọi là 'std :: terminate'? Tôi tin rằng tiêu chuẩn không giải quyết điều này một cách rõ ràng. – DeiDei

+0

Tôi tin rằng đó là hành vi không xác định (hoặc có thể không xác định?) –

+0

Tôi muốn nói về chủ đề thực sự thiết lập trình xử lý, mặc dù idk –

Trả lời

2

câu trả lời Số tiền này lên câu trả lời được đưa ra trong ý kiến ​​và một câu trả lời đã được xóa:

  • Nó không được quy định trong tiêu chuẩn (DeiDei, tôi đã kiểm tra quá trong N4618)

  • Tuy nhiên , vì lý do kỹ thuật, có khả năng người xử lý không được gọi trong một chủ đề khác mà người xử lý đã gọi đến số std::terminate (Galik, Hans Passant)

  • nó đã được xác minh trên trình biên dịch trực tuyến (Rinat Veliakhmedov), trình xử lý chấm dứt được gọi trong chuỗi gây chấm dứt được gọi.

Bạn có thể kiểm tra nó cho mình với mã này từ một câu trả lời đã xóa:

#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(); 
} 

Kết luận Đó là chưa xác định nhưng có vẻ như xử lý luôn được gọi trong các chủ đề gây std::terminate để được gọi là. (được thử nghiệm trên gcc-5.4, gcc-7.1, clang-3.8 với pthreads)

Các vấn đề liên quan