2015-02-11 61 views
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個參數的函數」,我不知道爲什麼。期貨是否不允許將它們放入容器中,如矢量?

如果是這樣,我應該以不同的方式來處理這個問題,還是有不同的方法來捕捉未來的清單?即我必須使用打包的任務嗎?

理想情況下,我想這應該與核心數量更接近,而不是隨意分解塊中的響應,然後嘗試爲每個塊創建一個線程。

+0

是否是'Service :: GetResponse()'靜態成員函數? – ikh 2015-02-11 03:09:51

+0

不。這只是一個普通的班級功能。 – user3072517 2015-02-11 03:11:24

+0

然後,爲什麼你不在'std :: async'中傳遞對象? 'GetResponse'有4個參數 - **'this' **,'defn','top'和'skip'。 – ikh 2015-02-11 03:12:54

回答

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

由於GetResponse不是靜態成員函數,因此應該給該對象作爲參數。


我不知道你做什麼正是,所以我不能給你具體的建議> 0 <

但是,如果你有興趣的異步任務與future,我會爲您介紹boost.asio。它是一個異步I/O庫(是的,AS時間/),它很容易地與std::futureboost::future合作。 (見this my question

在你的代碼中,我認爲Parse()也可以進入future

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

如果Parse不需要在同一個線程中運行或sequently運行,我認爲這是更好 - 你可以同時運行多個Parse和幾個GetResponse

+0

我已經將此標記爲答案(實際上我只是使用了pService),因爲它解決了編譯時的基本問題。 我不允許合併提升,所以我試圖確保期貨的使用是有效的,沒有併發問題需要擔心。 – user3072517 2015-02-11 03:42:53

+0

@ user3072517順便說一下,您的Web請求I/O可以更高效地並行處理?我猜只是單線程I/O和多線程解析就足夠了> o < – ikh 2015-02-11 03:49:41

+0

是的,單個請求是真正的單線程,但按批處理大小分解,以便可以在請求其他批處理時進行解析。批處理閾值足夠高,解析時間幾乎與請求時間相匹配,所以我不必使其以真正的多線程方式工作。不過,這樣做可能會更好。謝謝您的幫助! – user3072517 2015-02-11 04:00:21