问题
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?
回答1:
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.
回答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
来源:https://stackoverflow.com/questions/60336780/why-stdasync-runs-functions-with-a-same-thread