1

std::async returns:

An object of type future<result_of_t<decay_t<F>(decay_t<Args>...)>> that refers to the shared state created by this call to async. [ Note: If a future obtained from std::async is moved outside the local scope, other code that uses the future must be aware that the future destructor may block for the shared state to become ready. — end note ]

The returned std::future<> blocks on destruction until the value is available. However the normal destructor of std::future<> does not block:

~future();

Effects:

— releases any shared state (30.6.4);

— destroys *this.

As such the std::future<int>s in the the following example behave differently, even though they have the same type. Note, that this example does not trigger the block-on-destruction behaviour.

#include <chrono>
#include <future>
#include <iostream>
#include <thread>

int main()
{
    using namespace std::literals;
    // get a std::future<> by std::async<>();
    std::future<int> BlockingFuture = std::async([]() {std::this_thread::sleep_for(1s); return 1; });

    // get a std::future<> by packaged_task<>
    std::packaged_task<int()> task([]() {std::this_thread::sleep_for(1s); return 2; });
    std::future<int>          NonBlockingFuture = task.get_future();
    std::thread               task_thread(std::move(task));

    std::cout << "BlockingFuture.get(): " << BlockingFuture.get() << std::endl
              << "NonBlockingFuture.get(): " << NonBlockingFuture.get() << std::endl;

    task_thread.join();
    return 0;
}

What does std::async<> do to the std::future<> to make it block on destruction?

I already know why std::async is designed this way - I want to know how it works internally. See this document for the motivations behind std::async: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3451.pdf.

I cited from this draft: http://open-std.org/JTC1/SC22/WG21/docs/papers/2013/n3797.pdf

Yakk - Adam Nevraumont
  • 262,606
  • 27
  • 330
  • 524
Danish
  • 407
  • 3
  • 10
  • 1
    Which implementation? There are at least 3 major std implementations, and the standard does not specify how this feature works. – Yakk - Adam Nevraumont Nov 23 '20 at 14:25
  • I use gcc 10.2 with the standard library shipped with it – Danish Nov 23 '20 at 14:27
  • 1
    `std::future` is really bad. really. for "futures" that also support `co_await`, executors and whatnot, you can use my [concurrencpp](https://github.com/David-Haim/concurrencpp) – David Haim Nov 23 '20 at 15:00
  • 1
    Please see this question :https://stackoverflow.com/questions/63843676/why-stdfuture-is-different-returned-from-stdpackaged-task-and-stdasync – gaurav bharadwaj Nov 23 '20 at 16:34

0 Answers0