std::launch::async is blocking like a sync process
I am running Visual Studio 2012 and attempting to learn how std::async works. I have created a very simple C++ console application:
#include "stdafx.h"
#include <future>
#include <iostream>
void foo() {
std::cout << "foo() thread sleep" << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(5));
std::cout << "foo() thread awake" << std::endl;
}
int main()
{
std::future<void> res = std::async(std::launch::async, foo);
res.get();
std::cout << "MAIN THREAD" << std::endl;
system("pause");
return 0;
}
My initial expectation was to see "MAIN THREAD" printout appearing before "foo() thread awake" since the two threads are running asynchronously, with the foo() trailing behind due to its sleeping behavior. However, that is not what is actually happening. The call to res.get() blocks until foo() wakes up, and only then does it get to the "MAIN THREAD" printout. This is indicative of a synchronous behavior, so I am wondering what if perhaps I am either missing something, or not fully grasping the implementation. I have looked through numerous posts on this matter, but still cannot make any sense of it. Any help would be appreciated!
res.get();
blocks until the async is done.
http://en.cppreference.com/w/cpp/thread/future/get
Regardless of how you tell it to run, get
can't give you the results until it's done.
Well, this is how std::future::get
works - it blocks until future
has some result or exception to provide.
that doesn't mean that async
works synchronously, it is working asynchronously, it's only because you block the thread which waits on the result.
the idea was to to launch some task asynchronously, do something meanwhile and only call get
when you need the result, as you might figured out, it is not the most scale-able thing..
if you use Visual Studio 2015, you can access the await
keyword both for std::future
and concurrency::task
(Microsoft PPL library) , and for your own compatible defined types. this achieves non-blocking behavior.
#include "stdafx.h"
#include <future>
#include <iostream>
void foo() {
std::cout << "foo() thread sleep" << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(5));
std::cout << "foo() thread awake" << std::endl;
}
std::future<void> entry(){
await std::async(std::launch::async, foo);
std::cout << "foo has finished, back in entry()n";
}
int main()
{
std::cout << "MAIN THREAD" << std::endl;
entry();
std::cout << "BACK INMAIN THREAD" << std::endl;
system("pause");
return 0;
} //make sure to compile with /await flag
The problem is that res.get()
has to wait for its thread to finish before getting its result (if any). To see the concurrency in motion you need to move the get()
to after the other code that you want to run at the same time.
This example may make it a little clearer:
#include <ctime>
#include <cstdlib>
#include <future>
#include <iostream>
void foo(int id) {
std::cout << "foo(" << id << ") thread sleep" << std::endl;
// random sleep
std::this_thread::sleep_for(std::chrono::seconds(std::rand() % 10));
std::cout << "foo(" << id << ") thread awake" << std::endl;
}
int main()
{
std::srand(std::time(0));
std::future<void> res1 = std::async(std::launch::async, foo, 1);
std::future<void> res2 = std::async(std::launch::async, foo, 2);
std::future<void> res3 = std::async(std::launch::async, foo, 3);
std::cout << "MAIN THREAD SLEEPING" << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(20));
std::cout << "MAIN THREAD AWAKE" << std::endl;
// now wait for all the threads to end
res1.get();
res2.get();
res3.get();
system("pause");
return 0;
}
链接地址: http://www.djcxy.com/p/30736.html