【问题标题】:Starting an async task from a lambda blocks current thread c++从 lambda 启动异步任务会阻塞当前线程 c++
【发布时间】:2021-06-15 00:38:00
【问题描述】:

我正在从 lambda 函数中启动 std::async。 即使使用std::launch::async 策略,任务也会在同一个线程上同步运行,因此会阻塞它。 这是正常的还是我错过了什么?

int main()
{
    auto lambda = [&]
    {
        auto future = std::async(std::launch::async, [&]
        {
            using namespace std::chrono_literals;
            const auto delay = 5000ms;
            std::this_thread::sleep_for(delay);
            std::cout << "Done okay byeeeeeeee \n";
        });
    };
    
    lambda();
    for (long long i = 0 ; i < 10 ; ++i)
    {
        std::cout << "Doing stuff in main thread" << std::endl;
    }
}

【问题讨论】:

    标签: c++ multithreading asynchronous


    【解决方案1】:

    我上次遇到了类似的问题,没有用 std::async 解决,而是用 std::thread 解决。

    void get_sleep()
    {
        std::this_thread::sleep_for(std::chrono::seconds(5));
        std::cout << "Done okay byeeeeeeee \n";
    }
    
    int main()
    {
        std::thread t(get_sleep);
        t.detach();
    
        for (int i = 0 ; i < 10 ; ++i)
        {
            std::cout << "Doing stuff in main thread" << std::endl;
        }
    
        return 0;
    }
    

    【讨论】:

      【解决方案2】:

      问题在于future 变量,或者更确切地说是它的destruction

      析构函数可以阻塞直到异步完成。

      【讨论】:

      • 即使我删除了未来变量,它仍然会阻塞
      • @blondbeer 即使您没有将返回的对象分配给变量,std::async 仍然会创建并返回它。
      【解决方案3】:

      扩展至Some programmer dude's answer

      考虑下面的类→我创建它是为了查看析构函数何时被调用。

      struct MyStruct {
          ~MyStruct() {printf("DTOR\r\n");}
      };
      

      这是你的代码,我已经对代码进行了大量注释,所以让代码来说话

      int main(){
      //1 You are on main thread, create lambda on main thread
      auto lambda = [&]{
          //3 lambda is being started to execute
          MyStruct myStruct{}; //4 This I added
          //4 std::async enqueues the inner lambda, which will run and return in the future
          auto future = std::async(std::launch::async, [&]
          {
              using namespace std::chrono_literals;
              const auto delay = 5000ms;
              std::this_thread::sleep_for(delay);
              std::cout << "Done okay byeeeeeeee \n";
          });
          //5 Going out of scope, destructors will be called therefore you will be blocked
      };
      //2 You are on main thread    
      // You execute lambda on main thread, now you will enter into its contents    
      lambda();
      //6 After all destructors run you will continue here
      

      【讨论】:

        猜你喜欢
        • 2017-07-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-10-06
        • 2014-08-10
        • 2018-04-16
        • 1970-01-01
        相关资源
        最近更新 更多