Подтвердить что ты не робот

Параллельная обработка фьючерсов на С++

Я использую std::futures для параллельного обработки моего алгоритма. Я разделил информацию во взаимоисключающие пулы и затем выполнил одну и ту же операцию в каждом пуле в своем потоке. Код выглядит следующим образом:

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();
    }
};

Мой вопрос заключается в том, как справиться с ситуацией, когда исключение выбрано в Processor:Do()? В настоящее время я поймаю исключение с помощью future, а затем дождаться нуля секунд для каждого future, который еще не завершился; это прекрасно - эти потоки просто прекратятся, и обработка не будет завершена. Однако я не представил условия гонки в блоке catch. a future может завершиться между вызовами valid() и wait_for(), или это не вызывает беспокойства, поскольку я не звоню get() на эти неполные фьючерсы?

4b9b3361

Ответ 1

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

Там нет состояния гонки.