如何重新计划并发任务
How to reschedule a concurrent task?
粗体的简短解释。
我有一个tbb::task可以总结为:
class UpdateTask
: public tbb::task
{
public:
tbb::task* execute()
{
// some work...
if( can_continue() )
{
// make sure this is re-executed
this->recycle_to_reexecute(); //looks like it is deprecated but it's more clear to me
return nullptr; // ? or this? or tbb::empty_task?
}
return nullptr;
}
};
我希望此任务在完成后立即重新安排,直到满足条件。我以这种方式分配此任务:
UpdateTask& updater = *new(tbb::task::allocate_root()) UpdateTask();
不确定它与问题有关。
问题:当我运行代码时,我从 tbb(最新修订版,4.1.5)获得断言(在调试中),但我找不到使其正常工作的方法。
我已经重新阅读了文档,但我找不到一个简单的例子,我也不清楚我做错了什么。我做了一些实验:
- 使用我刚刚显示的代码,断言说我应该返回一个任务:
Assertion t_next failed on line 485 of file ...itbbsrctbbcustom_scheduler.h Detailed description: reexecution requires that method execute() return another task
- 然后,如果我返回这个,断言说应该分配任务:
Assertion t_next->state()==task::allocated failed on line 452 of file ...itbbsrctbbcustom_scheduler.h Detailed description: if task::execute() returns task, it must be marked as allo cated
- 在疑问中,我试图返回我动态创建的 tbb::empty_task(用于检查),并分配为
new(tbb::task::allocate_child()) tbb::empty_task()
.我得到了这条消息的断言Assertion p.ref_count==0 failed on line 107 of file ...itbbsrctbbcustom_scheduler.h Detailed description: completion of task caused predecessor's reference count to underflow
.
那么,该怎么做呢?我认为它很简单,但找不到完成的方式。它与任务引用计数有关吗?
更新:这是一个完整的代码,它很好地接近了我所拥有的内容:
#include <iostream>
#include <atomic>
#include <tbb/tbb.h>
namespace test { class UpdateTask : public tbb::task { public:
UpdateTask() { std::cout << "[UpdateTask]" << std::endl; }
~UpdateTask() { std::cout << "n[/UpdateTask]" << std::endl; }
tbb::task* execute() { std::cout << "Tick "<< m_count <<std::endl;
++m_count;
// make sure this is re-executed this->recycle_to_reexecute(); //return new(tbb::task::allocate_continuation()) tbb::empty_task(); return nullptr; }
private:
std::atomic<int> m_count;
};
tbb::task_list m_task_list;
void register_update_task() { UpdateTask& updater =
*new(tbb::task::allocate_root()) UpdateTask(); m_task_list.push_back( updater ); }
void run_and_wait() { tbb::task::spawn_root_and_wait( m_task_list ); }
void tbb_test() { register_update_task(); run_and_wait();
}
}
int main()
{
test::tbb_test();
std::cout << "nEND";
std::cin.ignore();
return 0;
}
所以,这里我得到了第一个例外,说我应该返回一个任务。在execute()
函数中,如果我用注释的返回替换返回,那么它似乎可以工作,但这有两个问题:
- 每次完成要执行的调用时,我都必须创建一个empty_task任务???
- 在第一次调用 execute() 后,主线程恢复。这不是spawn_root_and_wait()应该做的。在所有任务未完成并正确重新安排后。
我必须得出结论,这也不是正确的方法。
this->recycle_to_reexecute();
已弃用。
替换为:
this->increment_ref_count();
this->recycle_as_safe_continuation();
享受
附言:结束当然(在你的例子中)从执行返回 NULL。
相关文章:
- 控制允许动态运行c++的并发操作数
- 节俭并发:未解决的外部问题
- 有没有任务栏API可以立即应用注册表更改
- 如何创建线程序列以按照启动顺序执行任务?
- 并发/多线程:是否可以以这种方式生成相同的输出?
- C++一个线程如何正确通信其任务已完成?
- 在线程之间拆分任务总是值得的吗?
- 递归求和任务的错误答案
- Windows 并发运行时任务计划,但有例外
- 在iOS设备上执行并发任务时如何设置正确的线程数?
- 根据硬件并发性将任务平均划分为线程
- 混合并发:: parallel_for和async任务
- 为并发运行时实现任务本地变量
- 如何重新计划并发任务
- 解释此并发中的"="符号参数::任务调用
- 异步用于基于任务的并发
- 如何在c++中处理阻塞调用的并发任务
- 如何从结果创建并发性::任务
- 异常处理,WinRT c++并发异步任务
- 如何告诉c++并发运行时重用前一个线程来执行任务