使 TBB 管道过滤器超时

Timeout a TBB pipeline filter

这就是我要实现的目标:

我正在使用 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 returns 之前,它发出事件信号

SetEvent(event);

所以现在,如果 delayMS 超时到期,TBB 过滤器不会延迟整个管道。问题是 MyFunc 仍在后台运行,不会停止。

我的问题是,是否有更好的方法在 TBB 过滤器上设置超时,是否有解决方案来在达到超时后停止 MyFunc 的执行(我不想在其中使用计时器或计时检查,也许以某种方式使用事件并检查它是否被过滤器或其他东西占用)

是否可以为您的长期 运行 任务添加检查点?如果可能,您可以使用 task_grouptask_group_context 来取消一个或多个任务的执行。但是,要使其与 long-运行 任务一起正常运行,您需要通过 tbb::task::self().is_cancelled() 检查取消请求并终止任务执行来手动中断它。

然后,您可以使用额外的线程来监控时间,并向花费时间超过允许时间的任务组发送取消请求。这样一来,您的计算可以保持在同一线程上,因为管道会减少线程之间切换和同步的开销。

如果你的 long-运行 线程是 I/O 绑定的,那么你还有另一种选择,即引入异步 I/O ,它与 TBB 交互得更好,并让你对时间进行所有控制.