这就是我要实现的目标:
我正在使用 TBB 的
管道进行处理。我在管道中有几个过滤器,我需要过滤器尽可能快,因为这是一个实时应用程序。其中一个过滤器有时可能需要比我承受的时间更长的时间,所以我想以某种方式为该特定过滤器设置超时。
找了一段时间后,我找到了以下解决方案,该解决方案一般有效但存在问题:
创建过滤器时,我创建一个事件 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
的执行(我不希望在其中使用计时器或计时检查,也许以某种方式使用事件并检查它是否被过滤器或其他东西占用)
最佳答案
是否可以为长时间运行的任务添加检查点?如果可能,您可以使用 task_group
或 task_group_context
来取消一个或多个任务的执行。但是,为了使其在长时间运行的任务中正常运行,您需要通过 tbb::task::self().is_cancelled()
检查取消请求并终止任务来手动中断它执行。
然后,您可以使用额外的线程来监控时间,并向花费时间超过允许时间的任务组发送取消请求。通过这种方式,您的计算可以保持在同一个线程上,因为管道会减少线程之间切换和同步的开销。
如果您的长时间运行的线程受 I/O 限制,那么您还有另一种选择,即引入异步 I/O,它可以更好地与 TBB 交互,并让您随时间控制一切。
关于c++ - 使 TBB 管道过滤器超时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40779582/