Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

c++11 threads vs async

Consider the following two snippets of code where I am trying to launch 10000 threads:

Snippet 1

    std::array<std::future<void>, 10000> furArr_;
    try
    {
        size_t index = 0;
        for (auto & fut : furArr_)
        {
            std::cout << "Created thread # " << index++ << std::endl;
            fut = std::async(std::launch::async, fun);
        }
    }
    catch (std::system_error & ex)
    {
        std::string str = ex.what();
        std::cout << "Caught : " << str.c_str() << std::endl;
    }
    // I will call get afterwards, still 10000 threads should be active by now assuming "fun" is time consuming

Snippet 2

    std::array<std::thread, 10000> threadArr;
    try
    {
        size_t index = 0;
        for (auto & thr : threadArr)
        {
            std::cout << "Created thread # " << index++ << std::endl;
            thr = std::thread(fun);
        }
    }
    catch (std::system_error & ex)
    {
        std::string str = ex.what();
        std::cout << "Caught : " << str.c_str() << std::endl;
    }

The first case always succeeds .i.e. I am able to create 10000 threads and then I have to wait for all of them to finish. In the second case, almost always I end up getting an exception("resource unavailable try again") after creating 1600+ threads.

With a launch policy of std::launch::async, I thought that the two snippets should behave the same way. How different std::async with a launch policy of async is from launching a thread explicitly using std::thread?

I am on Windows 10, VS2015, binary is built in x86 release mode.

like image 565
Arun Avatar asked Jun 22 '17 02:06

Arun


People also ask

Does STD async create new thread?

If the deferred flag is set, a callable function will be stored together with its arguments, but the std::async function will not launch a new thread.

Should I use std async?

So if you want to make sure that the work is done asynchronously, use std::launch::async . @user2485710 it needs to block when you retrieve the result, if you need the result in the launching thread. It cannot use the result if the result is not ready. So if you go to get the result, you have to wait until it is ready.

What is std :: async?

The function template async runs the function f asynchronously (potentially in a separate thread which might be a part of a thread pool) and returns a std::future that will eventually hold the result of that function call. 1) Behaves as if (2) is called with policy being std::launch::async | std::launch::deferred.

How does C++ async work?

As the name indicates, C++ async is a function template fn, which takes functions or function objects as arguments (basically called callbacks) and runs them asynchronously. It returns the std:: the future object which is used to keep the result of the above function. The result is stored in the shared state.


1 Answers

Firstly, thanks to Igor Tandetnik for giving me the direction for this answer.

When we use std::async (with async launch policy), we are saying:

“I want to get this work done on a separate thread”.

When we use std::thread we are saying:

“I want to get this work done on a new thread”.

The subtle difference means that async (is usually) implemented using thread pools. Which means if we have invoked a method using async multiple times, often the thread id inside that method will repeat i.e. async allocates multiple jobs to the same set of threads from the pool. Whereas with std::thread, it never will.

This difference means that launching threads explicitly will be potentially more resource intensive (and thus the exception) than using async with async launch policy.

like image 120
Arun Avatar answered Sep 21 '22 01:09

Arun