blondbeer
blondbeer

Reputation: 45

Starting an async task from a lambda blocks current thread c++

I am starting a std::async from within a lambda function. Even with the policy std::launch::async, the task is running synchronously on the same thread and therefore blocking it. Is this normal or am I missing something?

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;
    }
}

Upvotes: 1

Views: 1133

Answers (3)

Expanding upon Some programmer dude's answer

Consider the following class→ I created this to see when the Destructor gets called.

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

Here is your code, I have heavily commented the code, so let the code do the talking

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

Upvotes: 0

Nico Verrijdt
Nico Verrijdt

Reputation: 75

I had a comparable problem last and didn't solve it with std::async but with 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;
}

Upvotes: 3

Some programmer dude
Some programmer dude

Reputation: 409176

The problem is the future variable, or rather the destruction of it.

The destructor can block until the async is finished.

Upvotes: 3

Related Questions