如何重新安排并发任务?

问题描述:

简要说明以粗体显示。如何重新安排并发任务?

我有一个TBB ::任务可以概括这样的:

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 ...\itbb\src\tbb\custom_scheduler.h Detailed description: reexecution requires that method execute() return another task
  • 然后,如果我回到这一点,断言说,任务应分配: Assertion t_next->state()==task::allocated failed on line 452 of file ...\itbb\src\tbb\custom_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 ...\itbb\src\tbb\custom_scheduler.h Detailed description: completion of task caused predecessor's reference count to underflow的断言。

那么,该怎么做呢?我认为这很简单,但无法找到完成的方式。 它与任务引用计数有关吗?


更新:这里是一个完整的代码是什么,我有一个很好的aproximation:

#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; 
} 

所以,在这里我得到了第一个例外,说我应该返回的任务。在​​功能,如果我取代由一个评论的回报,那么就表现为运行状态,但有两个问题:

  • 我要创建一个empty_task任务每次调用执行做? ??
  • 第一次调用execute()后,主线程恢复。这不是spawn_root_and_wait()应该做的。所有任务未完成并正确重新安排。

我必须得出结论,它不是正确的方法来做到这一点。

+0

这些断言是否显示任何错误消息?你可以添加它们吗? – 2012-08-07 14:12:55

+0

我复制粘贴我得到的断言。 – Klaim 2012-08-07 14:18:48

+0

在我看来,诀窍是至少有两个任务是彼此的延续?我有点迷路了...... – Klaim 2012-08-07 14:21:25

this->recycle_to_reexecute();

已弃用。

更换由

this->increment_ref_count(); 
this->recycle_as_safe_continuation(); 

享受

P.S:课程结束(在你的情况下)返回NULL从执行

+0

这工作! :D非常感谢。我只需编辑一下即可完成。 – Klaim 2012-08-07 15:45:27