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中有可能,但我现在需要一些东西,任何想法?
答案 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
这与关于如何拆分任务的线程池算法非常相似
我们有一个包含正在工作的节点的向量,
一个线程,大部分时间只是在向量上发生尺寸变化时才会睡觉和醒来。
当任务完成在节点上工作时,它可能会或可能不会将子项附加到向量中,但无论如何都会从中移除它。 检查线程醒来 - 如果向量为空 - 所有任务都已完成。