1

I was reading an article about concurrent programming with c++ (link). In this article, author shows a code that std::async runs two functions with the same thread. Also, when he used std::future with std::async, it acts differently again and runs all functions with independent threads. Why async behave like that and it has this uncontrolled manner? also, How can I develope a real concurrent program with this feature? is that possible at all or I should miss it?

2 Answers 2

7

I suggests to also read the reference, where it is better explained what happens, in the "Notes"-section

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 [...]

Or in other words std::async returns a std::future. Once that returned object gets destroyed it will wait until the running operation it represents ends. So, if you discard the return value like

std::async(xyz);

The destructor of the returned value gets called immediately after returning and thus waits for the completion of xyz.

If you keep the returned value like

auto futureXyz = std::async(xyz);

it does run parallel. That's because the returned value gets moved to the variable futureXyz, so the local variable "owns" the parallel executing function.

I wouldn't call this "uncontrolled behaviour", it's just something you would not expect, but it's well defined.

Sign up to request clarification or add additional context in comments.

7 Comments

But its not guaranteed to be run in parallel? It might run asynchronously but for the purpose of concurrency that doesnt help necessarily?
@TheGoldKnight23 I'm not 100% sure on this. You can specify some flag to force the creation of a new thread, but by default the implementation will decide this.
Which makes it less useful compared with std::thread for control over concurrency
Only when std::launch::async is set, a parallel processing is done.
@SKCoder std::launch::async and std::launch::deferred are both set by default, so the implementation decides what happens. But all of this can be found on the linked reference and in my opinion not of importance for the question at hand.
|
2

From the cppreference docs on std::async:

...runs the function f asynchronously (potentially in a separate thread...) (bold is mine).

std::async does not guarantee spawning a separate thread to execute the instruction, if you need a separate thread for definite use std::thread. This will guarantee a separate thread is spawned and you can communicate with it using std::future, atomic variables, etc.

Example code:

std::mutex cout_lock;
auto thread = std::thread([]{
  std::lock_guard<mutex> lock(cout_lock);
  std::cout << "Hello world from thread!\n";
});

std::lock_guard<mutex> lock(cout_lock);
std::cout << "Hello world!\n";
thread.join();

Notice how my above code uses mutex's since cout is not inherently thread-safe

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.