fileName.contains("foo") ) ) ftype = XML_FILE_PATTERN; if ( ftype != 0 ) { DirEntry dentry( fileName, ftype ); queueMutex.lock(); textFiles.push(dentry); queueMutex.unlock(); producerMutex.lock(); ++myFileCount; producerMutex.unlock(); bufferNotEmpty.wakeAll(); } } } // if - isDirectory / isRegular } // if } // while return true; } O metodo acima sera chamado exatamente uma vez, a partir do metodo run da minha implementacao do QThread no Mapper. Colocando o metodo depthFirstTraversal para rodar, primeiramente ele obtem todos os arquivos do diretoro, chamando o metodo entryList, da classe QDir. Entao um iterator e instanciado sobre a lista de arquivos anteriormente obtida, e, enquanto estiver iterando sobre os arquivos, e antes que qualquer coisa eu faco uma chamada a funcao wait da estrutura QWaitCondition: a wait condition e um tipo de variavel de condicao usada para sincronizar threads, interrompendo-o no caso de ter obtido 5 arquivos (claro, pode ser qualquer numero que voce queira). Porque obter exatamente 5 arquivos e interromper a execucao, esperando para que a estrutura QWaitCondition seja liberada? Isso e usado de forma a criar um buffer com capacidade para 5 arquivos (no maximo), a partir do qual o thread Reducer pode iterar sobre cada um dos arquivos listados pelo thread Mapper, abrir cada um desses arquivos, e procurar pelo criterio de busca dado. Dessa forma, o thread Reducer pode lidar apenas com uma lista de 5 arquivos, esgota-la, e depois permitir que o Mapper preencha com mais alguns novos arquivos encontrados. Essa e a primeira regra usada para sincronizar os 2 threads: Mapper, comece a cobrir o buffer com os nomes dos arquivos encontrados, ate que ele tenha 5 elementos. Dai, espere ate que o Reducer consuma alguns desses arquivos, pois a partir disso voce pode obter mais alguns arquivos. Faca isso ate o fim dos tempos. Agora, o thread Reducer, obtendo todos os arquivos que o Mapper consiga procurar: void KeySearchReduce::run() { DirEntry dirEntry; int cnt = 0; do { prod->producerMutex.lock(); if (prod->myFileCount == 0) { prod->bufferNotEmpty.wait(&prod->producerMutex); if (prod->isSearchDown()) { prod->producerMutex.unlock(); return; } } prod->producerMutex.unlock(); prod->queueMutex.lock(); dirEntry = prod->getFirstTextFile(); prod->queueMutex.unlock(); QFile infile(dirEntry.getFileName()); if (!infile.open(QIODevice::ReadOnly | QIODevice::Text) ) continue; QString line; unsigned int i = 0; QTextStream in(&infile); if ( dirEntry.getFileType() == FileSearchMap::TXT_FILE_PATTERN ) { while (!in.atEnd()) { line = in.readLine(); ++i; if ( i == 4 ) { lineP2Count += atol(line.toLocal8Bit().constData()); ++foundCount; break; } } // while } else if ( dirEntry.getFileType() == FileSearchMap::XML_FILE_PATTERN ) { while (!in.atEnd()) { line = in.readLine(); ++i; if ( i == 5 ) { lineP1Count += atol(line.toLocal8Bit().constData()); ++foundCount; break; } } // while } // if - getFileType() infile.close(); prod->producerMutex.lock(); prod->myFileCount--; prod->producerMutex.unlock(); prod->bufferNotFull.wakeAll(); } while (!prod->isSearchDown()); } O Reducer na primeira linha do comando do diz o seguinte: Ei Mapper, voce tem algum arquivo para que eu possa procurar pelo informacao numerica na linha X? Caso voce nao tenha arquivo algum, eu esperarei um pouco, ate que voce tenha algo para mim... Entao, para cada arquivo que o thread Reducer processa, ele avisara ao Mapper, de forma a que ele possa alimentar mais o buffer. No caso do Mapper estiver dormindo em um buffer cheio com 5