0

データ項目の数が多い場合、それを小さなリクエストに分割し、リクエストとその後のそのリクエストの解析を並行して実行したいという Web サービスからの応答があります。基本的に、最初のリクエストがデータを解析している間、後続のリクエストはそれを取得する必要があります。

これを行うにはいくつかのアプローチがあるようで、この場合は先物が適切かどうか疑問に思っています。先物は IO に使用すべきではなく、引数が逆になるというコメントを耳にします。

効果的に、私はこれをやろうとしています:

void Service::GetData(const Defn &defn) {
    // Split up the request into chunks if the  list is large
    size_t chunk_size = CONFIG.GetInt("Limits","BatchSize");
    if(chunk_size == 0) {
        auto response = GetResponse(defn);
        Parse(defn, *response);
    } else {
        std::vector<std::future<std::unique_ptr<Response>>> futures;
        for(int batch_num = 0; batch_num < (std::ceil(cardinality / chunk_size)); batch_num++) {
            futures.emplace_back(std::async(std::launch::async, &Service::GetResponse, defn, chunk_size, batch_num * chunk_size));
        }
        for(auto&& future : futures ) {
            Parse(defn, *future.get());
        }
    }
}

std::unique_ptr<Response> Service::GetResponse(const Defn &defn, size_t top, size_t skip) {
    // Do request and return response
}

しかし、「エラー C2064: 項が 3 つの引数を取る関数に評価されません」というエラーが表示され、その理由がわかりません。先物は、それらをベクターなどのコンテナーに入れることを禁止しますか?

もしそうなら、私はこれに別の方法でアプローチする必要がありますか、それとも先物のリストを取得する別の方法がありますか? つまり、パッケージ化されたタスクを使用する必要がありますか?

理想的には、応答を任意にチャンクに分割し、チャンクごとにスレッドを作成しようとするのではなく、これをコア数に近づける必要があると思います。

4

1 に答える 1

1
futures.emplace_back(
    std::async(std::launch::async,
        &Service::GetResponse, pService, defn, chunk_size, batch_num * chunk_size)
//                             ^^^^^^^^
    );

GetResponse は静的メンバー関数ではないため、オブジェクトをパラメーターとして指定する必要があります。


あなたが何をしているのか正確にはわからないので、具体的なアドバイスはできません >o<

ただし、 を使用した非同期タスクに興味がある場合は、 boost.asiofutureを紹介します。orと簡単に連携できる非同期 I/O ライブラリ (そう、AS同期I / O )です。(この私の質問を参照してください)std::futureboost::future

Parse()あなたのコードでは、 にも入ることができると思いますfuture

futures.emplace_back(
    std::async(std::launch::async,
        [&] { GetResponse(...); Parse(...); }
    )
);

同じスレッドで実行したり、順番に実行したりする必要がない場合Parseは、そのほうがよいと思います。Parse複数のスレッドGetResponseを並行して実行できます。

于 2015-02-11T03:28:53.860 に答える