使 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_group
或 task_group_context
来取消一个或多个任务的执行。但是,要使其与 long-运行 任务一起正常运行,您需要通过 tbb::task::self().is_cancelled()
检查取消请求并终止任务执行来手动中断它。
然后,您可以使用额外的线程来监控时间,并向花费时间超过允许时间的任务组发送取消请求。这样一来,您的计算可以保持在同一线程上,因为管道会减少线程之间切换和同步的开销。
如果你的 long-运行 线程是 I/O 绑定的,那么你还有另一种选择,即引入异步 I/O ,它与 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
returns 之前,它发出事件信号
SetEvent(event);
所以现在,如果 delayMS
超时到期,TBB 过滤器不会延迟整个管道。问题是 MyFunc
仍在后台运行,不会停止。
我的问题是,是否有更好的方法在 TBB 过滤器上设置超时,是否有解决方案来在达到超时后停止 MyFunc
的执行(我不想在其中使用计时器或计时检查,也许以某种方式使用事件并检查它是否被过滤器或其他东西占用)
是否可以为您的长期 运行 任务添加检查点?如果可能,您可以使用 task_group
或 task_group_context
来取消一个或多个任务的执行。但是,要使其与 long-运行 任务一起正常运行,您需要通过 tbb::task::self().is_cancelled()
检查取消请求并终止任务执行来手动中断它。
然后,您可以使用额外的线程来监控时间,并向花费时间超过允许时间的任务组发送取消请求。这样一来,您的计算可以保持在同一线程上,因为管道会减少线程之间切换和同步的开销。
如果你的 long-运行 线程是 I/O 绑定的,那么你还有另一种选择,即引入异步 I/O ,它与 TBB 交互得更好,并让你对时间进行所有控制.