简体   繁体   English

超时TBB管道过滤器

[英]Timeout a TBB pipeline filter

This is what I'm trying to achieve: 这就是我想要实现的目标:

I'm using TBB's pipeline for processing. 我正在使用TBB's管道进行处理。 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 创建过滤器后,我创建一个事件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 就在函数MyFunc返回之前,它会向事件发出信号

SetEvent(event);

So now, if the delayMS timeout expires, the TBB filter doesn't delay the entire pipeline. 所以现在,如果delayMS超时到期,TBB过滤器不会延迟整个流水线。 The problem is that MyFunc still runs in the background, it doesn't stop. 问题是MyFunc仍然在后台运行,它不会停止。

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) 我的问题是,有没有更好的方法在TBB过滤器上设置超时,并且有一个解决方案在达到超时后停止MyFunc的执行(我不想在其中使用定时器或定时检查,也许以某种方式使用该事件并检查它是否由过滤器或其他东西采取)

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. 如果可以,则可以使用task_grouptask_group_context取消任务或多个任务的执行。 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. 但是,要使其在长时间运行的任务中正常运行,您需要通过tbb::task::self().is_cancelled()检查取消请求并终止任务执行来手动中断它。

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. 如果您的长时间运行的线程受I / O限制,那么您可以通过引入异步I / O来更好地与TBB交互,并随着时间的推移为您提供所有控制。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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