多线程递归任务同步

时间:2015-09-25 09:34:31

标签: c++ multithreading recursion

void Node::recursiveThing()
{
  for(auto iter = m_children.begin();
  iter != m_children.end();
  iter++)
  {
    s_threadPool->addTask(std::bind(&Node::recursiveThing, (*iter));
  }
}

int main()
{
  Node * hugeThree = makeHugeTreeMethod();
  std::future allIterationsDone = s_threadPool->addTask(std::bind(&Node::recursiveThing, hugeTree));
  allIterationsDone.wait(); // I want to somehow block here until all spawned child tasks are done.
}

呀。

所以我的问题是我想从任务中生成子任务,这反过来会产生更多的子任务。这有效,但我怎么知道所有衍生的子任务都已完成?也许我需要创建一个线程安全列表,它们都被附加在哪里?

我在某处读过这可能在c ++ 17中有可能,但我现在需要一些东西,任何想法?

1 个答案:

答案 0 :(得分:1)

嗯...
是的,C ++ 17 std::when_all在这里可能非常有帮助。

我能想到的一个解决方案(仅限psudo代码!):

struct TreeTasks
   vector<child*> busyNodes
   mutex vectorLock
   condition_variable vectorCV
   thread taskChecker 

BeforeAll
 lock busyNodes
 add root-node's *this* to busyNodes
 unlock busyNodes
 launch taskChecker with taskChecker Routine

OnNodeTaskFinish
 lock vectorLock
 add child nodes pointers to busyNodes if exist
 remove *this* from busyNodes
 unlock busyNodes
 notify vectorCV

taskChecker Routine
  lock vectorLock
  wait on vectorCV(vectorLock) on predicate -> busyNodes.isEmpty()
  return done

这与关于如何拆分任务的线程池算法非常相似 我们有一个包含正在工作的节点的向量,
一个线程,大部分时间只是在向量上发生尺寸变化时才会睡觉和醒来。

当任务完成在节点上工作时,它可能会或可能不会将子项附加到向量中,但无论如何都会从中移除它。 检查线程醒来 - 如果向量为空 - 所有任务都已完成。