Multithreading 与std::async启动的并行性未发生,正在执行相同的线程

Multithreading 与std::async启动的并行性未发生,正在执行相同的线程,multithreading,c++11,asynchronous,Multithreading,C++11,Asynchronous,我试图利用std::async功能来实现并行性。但是如果我打印线程id,它总是返回相同的值。Semms喜欢按顺序运行此代码。我错过什么了吗 代码: int main() { bool check = false; auto func = [&](int i) { std::cout<<" i : "<<i<<" threa

我试图利用std::async功能来实现并行性。但是如果我打印线程id,它总是返回相同的值。Semms喜欢按顺序运行此代码。我错过什么了吗

代码:

int main()
{
    bool check = false;
    auto func = [&](int i) 
                          { 
                            std::cout<<"  i : "<<i<<"  thread_id : "<<std::this_thread::get_id()<<" ";
                            check = true;
                          }

    for(int j=0;j<10;j++)
    {
        std::async(std::async::launch, func, j);
    }

    std::cout<<" check : "<<check<<" ";

    return 0;
}

std::async
返回一个临时的未来对象,然后立即销毁该对象。允许在这种特定情况下阻塞,等待异步操作完成。这可能是您观察到的-
func
调用按顺序运行,并且恰好被分配到同一工作线程。

std::async
返回一个临时的未来对象,然后立即销毁该对象。允许在这种特定情况下阻塞,等待异步操作完成。这可能是您观察到的-
func
调用按顺序运行,并且恰好被分配到同一工作线程。

请注意:

如果从std::async获得的std::future未从引用中移动或绑定到引用,则std::future的析构函数将在完整表达式的末尾阻塞,直到异步操作完成,从而基本上使代码[…]同步

这正是你的情况。您需要处理
async
返回

#include <vector>
#include <future>
#include <iostream>
#include <chrono>
#include <mutex>

int main()
{
    auto func = [](int i) { 
      std::cout<<"  i : "<<i<<"  thread_id : "<<std::this_thread::get_id()<<"\n";
    };

    using Handle = std::future<void>; // pretty hard to be figured out automatically 
                                      // from lambda, but your function "returns" void
    std::vector<Handle> handles;
    for(int j=0;j<10;j++)
    {
        handles.push_back(std::async(std::launch::async, func, j));
        //result of std::async is implicitly moved onto the vector
    }

    return 0;
}
根据注释:

如果从std::async获得的std::future未从引用中移动或绑定到引用,则std::future的析构函数将在完整表达式的末尾阻塞,直到异步操作完成,从而基本上使代码[…]同步

这正是你的情况。您需要处理
async
返回

#include <vector>
#include <future>
#include <iostream>
#include <chrono>
#include <mutex>

int main()
{
    auto func = [](int i) { 
      std::cout<<"  i : "<<i<<"  thread_id : "<<std::this_thread::get_id()<<"\n";
    };

    using Handle = std::future<void>; // pretty hard to be figured out automatically 
                                      // from lambda, but your function "returns" void
    std::vector<Handle> handles;
    for(int j=0;j<10;j++)
    {
        handles.push_back(std::async(std::launch::async, func, j));
        //result of std::async is implicitly moved onto the vector
    }

    return 0;
}

您的代码不会占用任何时间,那么为什么它需要在多个线程中运行呢?通过不产生线程,它可以运行得更快。也许您应该使用实际消耗CPU时间的工作负载进行测试。我同意,但这是我展示的示例,无法粘贴实际代码,我正在“func”中执行一些繁重的操作。我对这个例子的意图是,如果它是正确的,或者我在概念上遗漏了一些东西。@JohnZwinck,我认为这无关紧要。表示“如果设置了async标志(即(policy&std::launch::async)!=0),那么async将在新的执行线程上执行可调用对象f,就像std::thread(std::forward(f)、std::forward(args)…)生成一样”。我知道这个标志应该强制生成新线程(即使它没有意义),并且应该反映在线程id中。您的代码不需要任何时间,那么为什么它需要在多个线程中运行呢?通过不产生线程,它可以运行得更快。也许您应该使用实际消耗CPU时间的工作负载进行测试。我同意,但这是我展示的示例,无法粘贴实际代码,我正在“func”中执行一些繁重的操作。我对这个例子的意图是,如果它是正确的,或者我在概念上遗漏了一些东西。@JohnZwinck,我认为这无关紧要。表示“如果设置了async标志(即(policy&std::launch::async)!=0),那么async将在新的执行线程上执行可调用对象f,就像std::thread(std::forward(f)、std::forward(args)…)生成一样”。我知道这个标志应该强制生成新线程(即使它没有意义),并且应该反映在线程id中。
  i : 6  thread_id : 47713265002240
  i : 7  thread_id : 47713267103488
  i : 8  thread_id : 47713269204736
  i : 9  thread_id : 47713271305984
  i : 5  thread_id : 47713262900992
  i : 4  thread_id : 47713260799744
  i : 3  thread_id : 47713258698496
  i : 2  thread_id : 47713256597248
  i : 1  thread_id : 47713254496000
  i : 0  thread_id : 47713252394752