简体   繁体   中英

Timeout a TBB pipeline filter

This is what I'm trying to achieve:

I'm using TBB's pipeline for processing. I have several filters in the pipeline and I need the filters to be as fast as possible since this is a real-time application. One of the filters can sometime take longer than I can afford it to, so I want to somehow set a timeout on that specific filter.

After looking for a while I found the following solution, which works in general but has its issues:

When the filter is created, I create an event HANDLE

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

Then, the filter calls a function using async and waits on the event

...
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;

Just before the function MyFunc returns, it signals the event

SetEvent(event);

So now, if the delayMS timeout expires, the TBB filter doesn't delay the entire pipeline. The problem is that MyFunc still runs in the background, it doesn't stop.

My question is, Is there a better way to set a timeout on a TBB filter, and is there a solution to stopping MyFunc 's execution once a timeout was reached (I'd prefer not to use timers or timing checks inside it, maybe somehow to use the event and check if it was taken by the filter or something)

Is it possible to add checkpoints to your long-running task? If this is possible, you can use task_group or task_group_context in order to cancel execution of a task or multiple tasks. However, for this to function properly with long-running task, you will need to manually interrupt it by checking for cancellation request via tbb::task::self().is_cancelled() and terminating the task execution.

Then, you can use additional thread for monitoring time and sending cancellation requests to the task groups which take longer than allowed. This way, your computation can stay on the same thread as the pipeline goes reducing overhead from switching and synchronizing between threads.

If your long-running thread is I/O bound, then you have another option by introducing async I/O which interacts with TBB much better and gives you all the control over time.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM