void DivideTree( void ){ while (true) {// взяли нод для деления// нет больше нодов - все сделано (для МП варианта это неверно) Node * theNode = GetNodeFromTree(); if (!theNode) break; // делим нод Node * child0, * child1; DivideNode(theNode, &child0, &child1);// если получившиеся новые ноды еще достаточно велики - добавим их в дерево if (IsNodeBig(child0)) AddNodeToTree(child0); if (IsNodeBig(child1)) AddNodeToTree(child1); }}
void DivideTree( void ){#pragma parallel блабла // каким-то образом параллелим цикл while (true) { sem++; //открыли семафор// взяли нод для деления Node * theNode = GetNodeFromTree(); // тредобезопасный пул нодов if (!theNode) { sem--; //нить "закончилась" bool end = sem.wait_for_zero(timeout); // ждем завершения остальных нитей if (end) break; else continue; // анализируем код возврата - если выпали по таймауту, идем на след виток, если дождались 0, работа закончена } // делим нод Node * child0, * child1; DivideNode(theNode, &child0, &child1);// если получившиеся новые ноды еще достаточно велики - добавим их в дерево if (IsNodeBig(child0)) AddNodeToTree(child0); if (IsNodeBig(child1)) AddNodeToTree(child1); } sem--; // закрыли семафор}
void DivideTree( void ){ while (true) { <---- нитка 2 сейчас здесь sem++; Node * theNode = GetNodeFromTree(); if (!theNode) { sem--; bool end = sem.wait_for_zero(timeout); <---- нитка 1 сейчас здесь, end = true...}
void DivideTree( void ){ while (true) { LOCK_TREE; Node * theNode = GetNodeFromTree(); if (!theNode) { if (!theTaskActive) { UNLOCK_TREE; break; } else { UNLOCK_TREE; continue; } } ++theTaskActive; UNLOCK_TREE; Node * child0, * child1; DivideNode(theNode, &child0, &child1); LOCK_TREE; if (IsNodeBig(child0)) AddNodeToTree(child0); if (IsNodeBig(child1)) AddNodeToTree(child1); --theTaskActive; UNLOCK_TREE; }}
QSemaphore sem(1); //изначально имеем 1 нодуvoid startThreads( void ) { for(i=0; i<MaxThreadCount; ++i) { // создаем и запускаем Потоки; }}void DivideTree( void ) { while (true) { // счетчик у семафора соответствует кол-ву доступных Node в списке // если он 0, то будем отдыхать на семафоре sem.acquire(); Node * theNode = GetNodeFromTree(); //потокобезопасна if (!theNode) { // не получили Node - их больше не будет, // разблокируем остальные Threads они тоже не получат Node и выйдут sem.release(); break; } // делим нод Node * child0, * child1; DivideNode(theNode, &child0, &child1);// если получившиеся новые ноды еще достаточно велики - добавим их в дерево if (IsNodeBig(child0)) { AddNodeToTree(child0); //потокобезопасна // увеличиваем счетчик семафора, добавился нод в список sem.release(); } if (IsNodeBig(child1)) { AddNodeToTree(child1); //потокобезопасна // увеличиваем счетчик семафора, добавился нод в список sem.release(); } }}
QSemaphore sem(1); //изначально имеем 1 нодуQMutex locker;int ActiveThreadCount = 0;void startThreads( void ) { for(i=0; i<MaxThreadCount; ++i) { locker.lock(); ActiveThreadCount++; locker.unlock(); // создаем и запускаем Поток; }}void DivideTree( void ) { while (true) { // счетчик у семафора соответствует кол-ву доступных Node в списке // если он 0, то будем отдыхать на семафоре locker.lock(); --ActiveThreadCount; if(!sem.tryAcquire()) { if(!ActiveThreadCount && !GetNodeCount()) { locker.unlock(); sem.release(); break; } else { locker.unlock(); sem.acquire(); locker.lock(); } } ++ActiveThreadCount; Node * theNode = GetNodeFromTree(); locker.unlock(); if (!theNode) { // не получили Node - их больше не будет, // разблокируем остальные Threads они тоже не получат Node и выйдут sem.release(); break; } // делим нод Node * child0, * child1; DivideNode(theNode, &child0, &child1);// если получившиеся новые ноды еще достаточно велики - добавим их в дерево if (IsNodeBig(child0)) { locker.lock(); AddNodeToTree(child0); locker.unlock(); // увеличиваем счетчик семафора, добавился нод в список sem.release(); } if (IsNodeBig(child1)) { locker.lock(); AddNodeToTree(child1); locker.unlock(); // увеличиваем счетчик семафора, добавился нод в список sem.release(); } }}