2016-04-26 49 views
0

我一直在試用std:thread。我爲標準算術運算使用二進制表達式樹。我正在創建一個線程來執行計算,並希望檢查除以零。當線程啓動std::async時,異常從工作線程拋出並在主線程中捕獲得很好。當我用std :: thread啓動線程時,拋出異常時,出現運行時錯誤abort()。任何見解爲什麼它與std::async but not std :: thread`?std :: thread,在線程中發生異常導致Visual C++中止錯誤

// Declaration in the Expression.h file 
public: 
    static long double __stdcall ThreadStaticEntryPoint(void * pThis); 


long double __stdcall Expression::ThreadStaticEntryPoint(void * pThis) 
{ 
    long double calc; 

    Expression* pthrdThis = (Expression*)pThis; 
    calc = pthrdThis->Calculate(); 

    return calc; 
} 

case 6: 
    try { 
    // Below works when encountering divide by zero. 
    // The thrown exception is caught correctly 
    // Launch thread using the this pointer 

     std::future<long double> fu = std::async(std::launch::async, 
      ThreadStaticEntryPoint, this); 
     calc = fu.get(); 

     // When Creating a thread as below and I throw a divide by zero 
    // exception I get an error in visual C++. Below does not work: 

     //std::thread t1(&Expresson::Calculate, this); 
     //t1.join(); 

     // Below works fine also 
     //calc = Calculate(); 
    } 
    catch (runtime_error &r) 
    { 
      ShowMessage("LoadMenu() Caught exception calling Calculate()"); 
      ShowMessage(r.what()); 
    } 
    catch (...) { 
      ShowMessage("Exception caught"); 
     } 

long double Expresson::Calculate() 
{ 
    Expression *e; 
    long double calc = 0; 

    e = rep->GetExpression(); 
    if (e == NULL) 
    { 
     ShowMessage("Main Expression " + to_string(rep->GetMainExpIndex()) + " is NULL. "); 
     return 0; 
    } 

    calc = e->Calculate() 

    return calc; 
} 

//************************************************************ 
// Calculate - Calculates Lval/Rval, returns result 
//************************************************************ 
long double Divide::Calculate() 
{ 
    Expression* lop = this->getLOperand(); 
    Expression* rop = this->getROperand(); 
    long double Lval = 0, Rval = 0; 
    long double result = 0; 

    if (lop == NULL || rop == NULL) 
     return result; 

    Lval = lop->Calculate(); 
    Rval = rop->Calculate(); 
    //result = divides<long double>()(Lval, Rval); 
    // The throw error below causes the error 
    if (Rval == 0) 
     throw runtime_error("DivExp::Calculate() - Divide by zero exception occured. Rval = 0"); 

    result = Lval/Rval; 

    return result; 

} 
+0

你爲什麼期望它「工作」? (我把「工作」放在引號中,因爲這個程序工作正常;它只是沒有做你期望的) – immibis

+0

它確實是所有情況下所期待的。只有當我拋出一個異常時,當用std :: thread啓動線程時,我得到一個運行時中止()。如果線程以std :: async啓動,並且拋出一個異常,它會像我期望的那樣在主線程中被捕獲。你爲什麼說它沒有達到我的期望? –

+0

因爲在那裏你拋出一個異常,仍然是一個情況下,你在這種情況下,期望它不會做的情況下... – immibis

回答

3

即是預期的行爲:

參見std::thread documentation

線程立即開始基於結構相關聯的線程對象的執行(待定任何OS調度延遲),開始於頂作爲構造函數參數提供的高級函數。頂級函數的返回值被忽略,如果它通過拋出異常終止,則std :: terminate被稱爲。

std::async documentation

然後異步執行上一個新的執行線程函數f(含初始化所有線程當地人),就好像通過催生的std ::線(F,ARGS ... ),,只是如果函數f返回值或引發異常,它將存儲在可通過異步返回給調用者的std :: future訪問的共享狀態中。

+0

你是完全正確的我想它總是有助於閱讀組裝前的「指令」我總是有幾個螺絲遺留或失蹤。一,在我最後閱讀說明之前,非常感謝。 –

相關問題