Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does std::async call the function synchronously even with the specified std::launch::async flag

The function that I pass to std::async prints the current thread id. Inspite of calling with the std::launch::async flag, it prints the same thead id. It means that it calls the function synchronously. Why?

void PrintThreadId()
{
    std::cout << std::this_thread::get_id() << std::endl;
}

int main()
{
    for (int i = 0; i < 5; ++i)
    {
        auto f = std::async(std::launch::async, PrintThreadId);
        f.wait();
    }
}

The output is: 20936 20936 20936 20936 20936

Environment: VS 2015, W7.

Thank you in advance!

like image 524
Alex Avatar asked Mar 10 '23 20:03

Alex


2 Answers

You actually serialize the calls by waiting for each of them, as such the same thread may be reused without breaking the specification that the std::future is executed by a thread distinct from the caller thread

Wake us up when the following code shows the same Caller ThreadId with the rest of them:

void PrintThreadId()
{
    std::cout << std::this_thread::get_id() << std::endl;
}

int main()
{
    std::cout << "Caller threadId (to be different from any id of the future exec thread): ";
    PrintThreadId();

    for (int i = 0; i < 5; ++i)
    {
        auto f = std::async(std::launch::async, PrintThreadId);
        f.wait();
    }
}
like image 71
Adrian Colomitchi Avatar answered Apr 07 '23 01:04

Adrian Colomitchi


Your future's lifetime ends with the scope of each iteration of the function. The thread associated with it dies too. The implementation is free to reuse it later, i.e. in the next iteration of your loop.

If you modify the example code to print current thread id, you'll see that the current thread is different:

for (int i = 0; i < 5; ++i)
{
    PrintThreadId();
    auto f = std::async(std::launch::async, PrintThreadId);
    f.wait();
}

live demo

You should also consider that futures returned async are special - in the destructor they block until the task isn't finished. More info on Scott Meyers' blog, under the contrary title: std::futures from std::async aren't special.

like image 35
krzaq Avatar answered Apr 07 '23 03:04

krzaq