2015-09-25 3 views
2
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

А как насчет вектора фьючерсов? Возможно, вы можете перебрать этот вектор, вызывающий 'get()' для каждого элемента. – Galik

+5

Я бы просто использовал счетчик. Увеличивайте его каждый раз, когда вы добавляете задание этого типа и уменьшаете его каждый раз, когда вы завершаете. –

+0

@Galik Но, гм, я не знаю всех фьючерсов, когда делаю основную задачу. Когда будущее будет завершено, оно может вернуть больше фьючерсов и так далее. Но как мне это написать? std :: future >>>>> и так далее .. – 0xbaadf00d

ответ

1

hmmm ...
Да, 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 

это очень похож на алгоритм поточно-пула о том, как разделить задачи.
У нас есть вектор, который содержит узел, на котором работает,
поток, который большую часть времени просто спит и просыпается, когда на векторе происходит изменение размера.

Когда задача заканчивается для работы над узлом, она может добавлять или не добавлять дочерние элементы в вектор, но в любом случае удаляется из него. просыпается контрольная нить - если вектор пуст - все задачи выполняются.

+0

Да, это дает мне представление, я проверю его позже. – 0xbaadf00d

Смежные вопросы