C++ 标准::异步赢得';t在未存储返回值时生成新线程

C++ 标准::异步赢得';t在未存储返回值时生成新线程,c++,multithreading,asynchronous,C++,Multithreading,Asynchronous,假设我有lambafoo,它只做一些事情,不需要返回任何东西。 当我这样做时: std::future<T> handle = std::async(std::launch::async, foo, arg1, arg2); 我在这里遗漏了什么?来自just::thread: 如果策略是std::launch::async,则在其自己的线程上运行INVOKE(fff,xyz…。返回的std::future将在该线程完成时准备就绪,并将保存函数调用引发的返回值或异常。与返回的std:

假设我有lamba
foo
,它只做一些事情,不需要返回任何东西。 当我这样做时:

std::future<T> handle = std::async(std::launch::async, foo, arg1, arg2);

我在这里遗漏了什么?

来自
just::thread

如果策略是
std::launch::async
,则在其自己的线程上运行
INVOKE(fff,xyz…
。返回的
std::future
将在该线程完成时准备就绪,并将保存函数调用引发的返回值或异常。与返回的
std::future
的异步状态关联的最后一个future对象的析构函数将阻塞,直到future就绪


返回的未来不会被分配到任何地方,它的析构函数会在
foo
完成之前阻塞。

我想添加一个链接,链接到Herb Sutter的一篇文章,他在文章中认为期货永远不应该阻塞。

为什么阻塞

  • std::async()返回
    std::future
    临时对象
  • 临时对象立即被销毁,调用Destructor
  • std::future
    析构函数正在阻塞。这既糟糕又麻烦
  • 为什么分配是可以的

    通过给变量赋值,返回的对象不会立即销毁,而是在调用代码的作用域结束之前销毁

    代码示例:main1正常
    main2
    main3
    相当于阻塞主线程

    void forever() {
        while (true);
    }
    
    void main1() {
        std::future<void> p = std::async(std::launch::async, forever);
        std::cout << "printing" << std::endl; // can print, then forever blocking
    }
    
    void main2() {
        std::async(std::launch::async, forever);
        std::cout << "printing" << std::endl; // forever blocking first, cannot print
    }
    
    void main3() {
        {std::future<void> p = std::async(std::launch::async, forever);}
        std::cout << "printing" << std::endl; // forever blocking first, cannot print
    }
    
    void forever(){
    虽然(正确);
    }
    void main 1(){
    std::future p=std::async(std::launch::async,forever);
    
    std::cout可能由
    async
    返回的
    future
    立即被销毁。如果
    future
    的析构函数中有一个隐式的等待,我不会感到惊讶。这不是一篇文章,而是一个建议。除此之外,是的,生成
    ~future()
    块是一个错误。~future()默认情况下不会实际阻塞。它仅在从std::async返回时阻塞,因为async将阻塞状态分配给future,~future()必须释放它。>async将阻塞状态分配给future…@WojciechCierpucha但这是为什么?
    std::async(std::launch::async, foo, arg1, arg2);
    
    void forever() {
        while (true);
    }
    
    void main1() {
        std::future<void> p = std::async(std::launch::async, forever);
        std::cout << "printing" << std::endl; // can print, then forever blocking
    }
    
    void main2() {
        std::async(std::launch::async, forever);
        std::cout << "printing" << std::endl; // forever blocking first, cannot print
    }
    
    void main3() {
        {std::future<void> p = std::async(std::launch::async, forever);}
        std::cout << "printing" << std::endl; // forever blocking first, cannot print
    }