2017-08-11 88 views
-1

我有一個非常簡單的程序爲:C++ 11:Mac上的Clang不會捕獲std :: thread函數拋出的異常?

#include <iostream> 
#include <string> 
#include <thread> 
using namespace std; 
struct N{ 
    string s; 
    N(){} 
    ~N(){cout<<"N dtor"<<endl;} 
}; 

void f(){ 
    N n; 
    throw 0; 
} 
int main(){ 
    try{ 
     thread a(f), b(f); 
     a.join(); 
     b.join(); 
    }catch(exception& e){ 
     cout<<e.what()<<endl; 
    } 
    return 0; 
} 

在我的Mac +鐺環境,運行結果是:

libc++abi.dylib: terminating with uncaught exception of type int 
Abort trap: 6 

它不打印「N析構函數」,因爲我預期。所以我的問題,如果std :: thread函數拋出一個異常,如何捕捉/處理它?不能保證線程函數內的代碼不會拋出任何異常。

我試圖在Linux和異常可以被捕獲並打印:

Enable multithreading to use std::thread: Operation not permitted 

非常感謝。

+0

如果您想將異常傳輸到調用線程,請使用'std :: async'。 – ecatmur

回答

2

如果在線程中拋出異常,它必須被捕獲到同一個線程中(或者根本沒有)。在您的示例中,try塊可以特別從創建或加入線程的嘗試中捕獲異常,但不會捕獲線程中運行的代碼導致的異常。

如果你仔細想想,這就是它的原因。你的例子試圖確保你不會離開try塊,直到線程完成,但這通常不能得到保證。即使在你的例子中,如果連接調用試圖拋出源於目標線程的異常(它們沒有,但爲了爭論...),你永遠不會達到join(b)調用,並且沒有什麼可以保證當b的線程拋出異常時,您仍然位於try塊中。

一個線程的流量控制捕捉另一個線程的異常根本不起作用。如果您需要這種功能,您可以在工作線程中放置一個異常處理程序,並使用已建立的線程間通信機制將異常狀態通知給主線程。