未来的任务刚刚消失

时间:2017-01-13 20:40:51

标签: c++ c++11 future

使用std::futureThreadPool时我遇到了一个相当奇怪的情况,虽然我不认为它是ThreadPool(我正在使用https://github.com/bandi13/ThreadPool/blob/master/example.cpp)因为(我'我试过它的多个分叉,经过一些调试后,我看不出它与问题有什么关系)。

问题在于,在某些情况下,我的doProcess方法只是天堂 - 它不会返回。它只是在长时间运行的循环中消失。

因此,我认为我必须做错事,但无法弄清楚是什么。

以下是代码:

ThreadPool pool(numThreads);
std::vector< std::future<bool> > futures;

int count = 0;
string orgOut = outFile;
for (auto fileToProcess : filesToProcess) {
    count++;
    outFile = orgOut + std::to_string(count);

    // enque processing in the thread pool
    futures.emplace_back(
        pool.enqueue([count, fileToProcess, outFile, filteredKeys, sql] {
            return doProcess(fileToProcess, outFile, filteredKeys, sql);
        })
    );
}

然后我等待所有处理完成(我认为这也可以以更优雅的方式完成):

bool done = false;
    while (!done) {
        done = true;
        for (auto && futr : futures) {
            auto status = futr.wait_for(std::chrono::milliseconds(1));
            if (status != std::future_status::ready) {
                done = false;
                break;
            }
        }
    }

编辑:起初我也尝试了obvius wait(),但结果相同:

bool done = false;
while (!done) {
    done = true;
    for (auto && futr : futures) {
        futr.wait();
    }
}

编辑:doProcess()方法。行为是这样的:loopcnt变量只是一个计数器,用于调试方法输入和循环开始的频率。正如你所看到的,这个循环没有返回,但线程在这个循环内部消失时没有任何错误,并且偶尔只得到HereCnt(就像运行方法的100次中一样)。我真的很困惑。

bool doProcess([...]) {
    // ....
    vector<vector<KVO*>*>& features = filter.result();
    vector<vector<KVO*>*> filteredFeatures;
    static int loopcnt = 0;
    std::cout << "loops " << loopcnt << endl;
    loopcnt++;
    for (vector<KVO*>* feature : features) {
        for (KVO *kv : *feature) {
            switch (kv->value.type()) {
                case Variant::JNULL:
                    sqlFilter.setNullValue(kv->key);
                    break;

                    case Variant::INT:
                    sqlFilter.setValue(static_cast<int64_t>(kv->value), kv->key);
                    break;

                case Variant::UINT:
                    sqlFilter.setValue(static_cast<int64_t>(kv->value), kv->key);
                    break;

                case Variant::DOUBLE:
                    sqlFilter.setValue(static_cast<double>(kv->value), kv->key);
                    break;

                case Variant::STRING:
                    sqlFilter.setValue(static_cast<string>(kv->value), kv->key);
                    break;

                default:
                    assert(false);
                    break;
            }
        }
        int filterResult = sqlFilter.exec();
        if (filterResult > 0) {
            filteredFeatures.push_back(feature);
        }
        sqlFilter.reset();
     }

    static int wasHereCnt = 0;
    std::cout << "was here: " << wasHereCnt << endl;
    wasHereCnt++;

    JsonWriter<Writer<FileWriteStream>> geojsonWriter(writer, filteredFeatures);
        bool res = geojsonWriter.write();
        os.Flush();
        fclose(fp);

        return res;
}

doProcess方法在花费较少时间时可以正常工作。当需要更多时间时,它会中断并消失。差异只是我在方法中运行的SQL查询的复杂性。所以我不发布doProcess()的代码。

是什么原因导致线程池的线程被中断,以及如何解决它?

更新

好吧,我发现了。几个小时后,我决定删除未来的任务,然后在主线程上运行任务。问题是通过以下方式抛出异常:

抛出std :: runtime_error(“bad cast”);

...在此之后的代码流程中有一段时间了:

case Variant::UINT:
                sqlFilter.setValue(static_cast<int64_t>(kv->value), kv->key);
                break;

在主线程上运行时,此错误按预期抛出。但是,当它作为未来任务运行时,它永远不会被提升。这真的很奇怪,看起来像编译器或调试器问题。

0 个答案:

没有答案