Search code examples
multithreadingc++11stdasync

Using std::async in constructor


I am quite new to the C++11 feature std::async and I fail to grasp why the code below never prints bar.

Could someone shed some light on this for me?

class Thready {

  public:

    Thready() {
        std::async(std::launch::async, &Thready::foo, this);
    }

    void foo() {
        while (true) {
            std::cout << "foo" << std::endl;
        }
    }

    void bar() {
        while (true) {
            std::cout << "bar" << std::endl;
       }
    }
};

int main() {  
    Thready t;
    t.bar();
}

Solution

  • See "Notes" section on this page: http://en.cppreference.com/w/cpp/thread/async

    The implementation may extend the behavior of the first overload of std::async by enabling additional (implementation-defined) bits in the default launch policy. Examples of implementation-defined launch policies are the sync policy (execute immediately, within the async call) and the task policy (similar to async, but thread-locals are not cleared) If the std::future obtained from std::async is not moved from or bound to a reference, the destructor of the std::future will block at the end of the full expression until the asynchronous operation completes, essentially making code such as the following synchronous:

    std::async(std::launch::async, []{ f(); }); // temporary's dtor waits for f()
    std::async(std::launch::async, []{ g(); }); // does not start until f() completes
    

    (note that the destructors of std::futures obtained by means other than a call to std::async never block)

    TL;DR:

    try to save the returned value of std::async call into some variable:

    auto handle = std::async(std::launch::async, &Thready::foo, this);
    

    EDIT:

    the following code should work as you expect.

    #include <future>
    #include <iostream>
    
    class Thready {
    
      public:
    
        Thready() {
            handle = std::async(std::launch::async, &Thready::foo, this);
        }
    
        void foo() {
            while (true) {
                std::cout << "foo" << std::endl;
            }
        }
    
        void bar() {
            while (true) {
                std::cout << "bar" << std::endl;
           }
        }
    
        std::future<void> handle;
    };
    
    int main() {  
        Thready t;
        t.bar();
    }