2013-03-03 162 views
4

雖然這個問題不僅限於OpenKinect庫,但它是我能想出來的最好的例子。用線程捕捉異常

在C++ Wrapper for OpenKinect中,無論何時出現問題,它都會引發runtime_error異常。這個例子來自libfreenect.hpp。線程是在類的構造函數中創建的。

// Do not call directly, thread runs here 
void operator()() { 
    while(!m_stop) { 
     if(freenect_process_events(m_ctx) < 0) throw std::runtime_error("Cannot process freenect events"); 
    } 
} 

static void *pthread_callback(void *user_data) { 
    Freenect* freenect = static_cast<Freenect*>(user_data); 
    (*freenect)(); 
    return NULL; 
} 

我的問題很簡單:是否有可能以某種方式捕獲這些錯誤並處理它們?通常,我會處理異常,或重寫代碼:我不喜歡讓程序因爲異常而崩潰,如果我知道它們可能發生,我寧願處理它們。有一些圖書館做類似的事情,我不能重寫,所以我來問這個問題。

+0

爲什麼你不能處理異常?爲什麼不嘗試/ catch圍繞'(* freenect)();'呼叫? – 2013-03-04 15:57:39

+0

重點在於這是圖書館的一部分。雖然這是開源的,可以更改,但還有其他一些情況我無法更改。所以我只是想知道是否有可能使用pthreads從另一個線程捕獲拋出。 – AdmiralJonB 2013-03-04 16:42:26

+1

不是直接的,沒有。異常是基於堆棧的機制,也是線程特定的。如果你沒有在pthread中捕捉到它們,那麼這些線程將會被無聲地終止。向其他線程傳遞異常將需要catch中的線程間通信; – 2013-03-04 19:27:04

回答

0

你必須更清楚地定義線程的責任。我猜測它通過某種管道或併發隊列向某些其他線程提供了一些消息。在這種情況下,只需更改您的消息類來存儲異常信息(std :: exception_ptr)。當你訪問消息中的數據時,首先檢查是否包含異常;如果是這樣,請調用std :: rethrow_exception()。

在std :: future()中使用了類似的機制;或者你從其中獲得(或)承諾的價值,或者在嘗試這樣做時引發異常,這些異常來自另一個線程。搜索std :: async()示例以查看它的實際操作。