【问题标题】:Multiple Async Calls in C++C++ 中的多个异步调用
【发布时间】:2017-02-18 10:53:13
【问题描述】:

我想多次调用异步方法。一个简化的例子如下所示:

size_t counter(std::string &s)
{
    return s.size();
}

void stringCountAccumulator()
{
    std::vector<std::string> foos = {"this", "is", "spartaa"};
    size_t total = 0;
    for (std::string &s : foos)
    {
        std::future<size_t> fut = std::async(
            std::launch::async,
            counter, s);

        total += fut.get();
    }
    std::cout << "Total: " << total;
}

看起来,fut.get() 阻止了其他未来的调用。如何在 C++ 中实现这个问题?我需要在单独的线程中调用一个函数。这个函数“返回”一个值。

【问题讨论】:

    标签: c++ multithreading c++11


    【解决方案1】:
    void stringCountAccumulator()
    {
      std::vector<std::string> foos = {"this", "is", "spartaa"};
      std::vector<std::future<size_t>> calcs;
      for (auto&& s : foos) {
        calcs.push_back( std::async(
          std::launch::async,
          counter, s)
        );
      }
      std::size_t total = 0;
      for (auto&& fut:calcs)
        total += fut.get();
      std::cout << "Total: " << total << "\n";
    }
    

    .get() 正在阻塞。所以在你把所有任务都排队之前不要阻塞。

    另一种计划是编写/查找线程池,并让每个任务更新一个可能的原子(或互斥保护)计数器。

    拥有一个已完成任务的计数器(同样,可能是原子的)。

    有一个承诺(总计),当最后一个任务完成时(由最后一个任务完成)。

    从那个承诺中回报未来。现在你有了一个代表整个线程池的未来,计算它们的值并将其相加,具有很多并发性。

    一些框架,比如微软的 ppl,有一个系统可以为你做这样的事情;您有返回值的任务,以及组合这些值并从中获取组合结果的函数对象。

    【讨论】:

    • Yakk,我还有一个问题。如果有一个全局变量在计数器函数中更新,它有什么问题吗?喜欢size_t counter(std::string &amp;s, std::vector&lt;size_t&gt; &amp;listSize) { listSize.push_pack(s.size()); return s.size(); }
    • @fanfan 请使用 [ask question] 按钮提出有关堆栈溢出的问题。
    【解决方案2】:

    看看这个:C++ threads for background loading。这解释了如何获得任何已完成任务的结果。

    【讨论】:

    • 谢谢,我会检查的。没有回调机制吗?我必须检查任务是否完成吗?
    • 是的,您必须手动检查任务是否完成。
    【解决方案3】:

    您还需要声明 StringCountAccumulator() 将异步执行。也只有在未来准备好时才调用future::get()。这是一个代码 sn-p :

     std::future<void> stringCountAccumulator()
     {
        std::vector<std::string> foos = {"this", "is", "spartaa"};
        size_t total = 0;
        for (std::string &s : foos)
        {
            std::future<size_t> fut = std::async(
               std::launch::async, counter, s);
            while (!fut.is_ready() ) ;
            total += fut.get();
        }
       std::cout << "Total: " << total;
      }
    

    【讨论】:

    • 这应该返回一个future,但是return语句在哪里?
    • @smac89 我找不到任何具体的信息,但似乎这是correct and intended。表示这个函数是异步的,没有返回值。因此 void 作为模板参数。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-10-05
    • 1970-01-01
    • 2014-05-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-10
    相关资源
    最近更新 更多