2016-11-24 73 views
1

這就是我想要實現:超時一個TBB管道過濾

我使用TBB's管道進行處理。我有幾個過濾器,我需要過濾器儘可能快,因爲這是一個實時應用程序。其中一個過濾器在某些時候可能比我能負擔得起的時間要長,所以我想以某種方式在該特定過濾器上設置超時。

找了一段時間後,我發現了以下解決方案,這在一般的工作,但有它的問題:

在創建過濾器,創建活動HANDLE

m_Event = CreateEvent(NULL, FALSE, FALSE, NULL); 

之後,濾波器使用異步和等待的事件

... 
auto funcBind = std::bind(&MyFunc, ...) 
auto function = std::async(std::launch::async, funcBind, m_Event ...); 
long res = WaitForSingleObject(m_Event, delayMS); 
auto myFuncRes = function.get() 
if (res == WAIT_OBJECT_0 && (bool)myFuncRes) 
{ 
    // MyFunc Finished successfuly 
} 
else if (res == WAIT_TIMEOUT) 
{ 
    // Timeout expired 
} 
else 
{ 
    // MyFunc failed 
} 
... 
return; 

只需將功能MyFunc返回之前,它標誌着調用一個函數事件

SetEvent(event); 

所以,現在,如果delayMS超時,TBB過濾器不耽誤整個管道。問題是,MyFunc仍然在後臺運行,它不會停止。

我的問題是,是否有更好的方法來設置TBB過濾器的超時時間,並且有一個解決方案,一旦達到超時就停止MyFunc的執行(我不想使用定時器或定時檢查在其中,也許以某種方式使用該事件,並檢查它是否由過濾器或其他東西)

回答

3

是否可以將檢查點添加到您的長時間運行的任務?如果可以的話,您可以使用task_grouptask_group_context來取消執行任務或多個任務。但是,爲了在長時間運行的任務中正常工作,您需要通過tbb::task::self().is_cancelled()檢查取消請求並終止任務執行來手動中斷它。

然後,您可以使用其他線程來監視時間並將取消請求發送到比允許時間長的任務組。這樣,您的計算可以保持在同一個線程上,因爲管道可以減少線程間切換和同步的開銷。

如果你的長時間運行的線程是I/O綁定的,那麼通過引入與TBB交互的異步I/O更好,並給你所有的時間控制,你有另一種選擇。

+0

謝謝。取消task_group是否會停止管道?因爲我只想停止特定步驟的長過濾器。我想要管道繼續像往常一樣 –

+0

否如果您運行並取消只在task_group或其他'task_group_context :: isolated'區域的上下文過濾器,而不是整個管道的上下文。這意味着在過濾器函子內部,你想運行一些其他嵌套算法,如'task_group :: run_and_wait()',以便它運行在不同的上下文中 – Anton