Sto utilizzando std::futures
per elaborare in parallelo il mio algoritmo. Ho diviso le informazioni in pool reciprocamente esclusivi e poi ho eseguito la stessa operazione su ciascun pool in una propria discussione. Il codice è simile al seguente:Elaborazione parallela dei futures C++
class Processor
{
public:
Processor(const std::string &strVal) : m_strVal(strVal)
{
}
std::string GetVal() const {return m_strVal;}
std::vector<std::string> Do()
{
// do some processing - this can throw an exception
}
private:
std::string m_strVal;
};
class ParallelAlgo
{
private:
std::vector<std::string> m_vecMasterResults;
public:
ProcessingFunction(const std::vector<std::string> &vecInfo)
{
// vecInfo holds mutually exclusive pools
std::vector<std::future<std::vector<std::string> > > vecFutures(vecInfo.size());
try
{
for (auto n = 0 ; n < vecInfo.size() ; n++)
{
vecFuture[n] = std::async(std::launch::async, &ParallelAlgo::WorkFunc, vecInfo[n].GetVal());
}
for (auto it = vecFutures.begin() ; it != vecFutures.end() ; ++it)
{
std::vector<std::string> RetVal = it->get();
m_MasterResults.insert(m_MasterResults.begin(), RetVal.begin(), RetVal.end());
vecFutures.erase(it);
}
}
catch (exception &e)
{
for (auto it = vecFutures.begin() ; it != vecFuture.end() ; ++it)
{
// race condition?
if (it->valid())
{
it->wait_for(std::chrono::second(0));
}
}
}
}
std::vector<std::string> ParallelAlgo::WorkFunc(const std::string &strVal)
{
Processor _Proccessor(strVal);
return _Processor.Do();
}
};
La mia domanda è come gestire la situazione quando viene generata un'eccezione in Processor:Do()
? Attualmente rilevo l'eccezione utilizzando future
, quindi attendo zero secondi per ogni future
che non è stato completato; questo va bene - questi thread terminano semplicemente e l'elaborazione non sarà completata. Tuttavia, non ho introdotto una condizione di gara nel blocco catch. un future
potrebbe finire tra le chiamate a valid()
e wait_for()
, o non è un problema dato che non sto chiamando get()
su questi futuri incompleti?
Chiamare 'wait_for' su un thread' finito' funziona esattamente come ci si aspetterebbe, ritorna immediatamente. Non vedo il problema – nwp
Come non fai nulla con l'eccezione, non potresti non preoccuparti solo dei thread incompleti? I distruttori di 'std :: future' verranno bloccati fino al termine dell'elaborazione asincrona, se necessario, ma per quanto ho capito è quello che vuoi. –
C'è un bug nel codice di esempio. Chiamare 'vecFutures.erase (it);' invaliderà 'it' e usarlo ulteriormente nel ciclo for è UB. – DaBrain