2015-02-11 62 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