If we want to get the thread processing result asynchronously, we can use future and async. async returns a future object, and the waiting thread can obtain the processing value of the asynchronous thread on the future object. The asynchronous here, in fact, the main thread will block.
[1] The state of future
A future has three states:
std::future_status::deferred; //表示异步线程还未启动
std::future_status::ready; //表示异步线程已经执行完毕,并已经将执行结果写入到future中
std::future_status::timeout; // 表示异步线程处理超时,并没有将结果写入future中
[2] Whether async starts the thread
Whether async starts an asynchronous thread is determined by the first parameter of async. The async interface is defined as follows:
async(std::launch::async | std::launch::deferred, f, args...)
The first parameter indicates the way to start the asynchronous thread. There are two ways:
std::launch::async; // 表示表用async函数后,立即启动异步线程
std::launch::deferred; // 表示线程延迟启动,当调用future.get或者future.wait时,才会创建异步线程并启动
The default method of async is shown in the interface:
std::launch::async | std::launch::deferred // 表示是否启动线程由系统负载决定,如果系统负载过重,则可能不启动异步线程计算,则此时future的状态不会为ready, 一般情况下,这种默认设置够用了,但是如果需要一定以异步线程的方式执行,则显示修改启动方式为async
[3] Four methods of future
future<int> fu;
fu.get();
The get declaration is as follows:
Returns the int value accessed in the future, get will block until it gets the data
fu.wait();
The wait statement is as follows:
No return value, keep waiting until the future state is ready
fu.wait_for();
wait_for is declared as follows:
Wait for a certain time, the return value is the state of future, if the wait times out, return time_out
fu.wait_until(); is to wait until a certain point in time, similar to wait_for.
[4] async uses the default startup parameters
#include<iostream>
#include<thread>
#include<mutex>
#include<condition_variable>
#include<future>
#include<chrono>
using namespace std;
int f(int i)
{
cout << "start" << endl;
cout << "this thread id = " << std::this_thread::get_id() << endl;
std::this_thread::sleep_for(2s);
cout << "end" << endl;
return i;
}
int main(int argc, int * argv[])
{
future<int> fu = std::async(f, 8);
cout << fu.get() << endl;
cout << "main thread id = " << std::this_thread::get_id() << endl;
cout << "main" << endl;
system("pause");
}
The result is as follows:
It can be seen that the thread ids are different here.
[5] Wait first, then get
#include<iostream>
#include<thread>
#include<mutex>
#include<condition_variable>
#include<future>
#include<chrono>
using namespace std;
int f(int i)
{
cout << "start" << endl;
cout << "this thread id = " << std::this_thread::get_id() << endl;
std::this_thread::sleep_for(2s);
cout << "end" << endl;
return i;
}
int main(int argc, int * argv[])
{
future<int> fu = std::async(f, 8);
fu.wait();
cout << fu.get() << endl;
cout << "main thread id = " << std::this_thread::get_id() << endl;
cout << "main" << endl;
system("pause");
}
The result is as follows:
【6】Wait for timeout
#include<iostream>
#include<thread>
#include<mutex>
#include<condition_variable>
#include<future>
#include<chrono>
using namespace std;
int f(int i)
{
cout << "start" << endl;
cout << "this thread id = " << std::this_thread::get_id() << endl;
std::this_thread::sleep_for(2s);
cout << "end" << endl;
return i;
}
int main(int argc, int * argv[])
{
future<int> fu = std::async(f, 8);
if (fu.wait_for(1s) == std::future_status::timeout) {
cout << "time out" << endl;
}
else {
cout << fu.get() << endl;
}
cout << "main thread id = " << std::this_thread::get_id() << endl;
cout << "main" << endl;
system("pause");
}
The result is as follows:
If it times out and still get it, it will continue to wait until the future state is ready, and then retrieve the data
#include<iostream>
#include<thread>
#include<mutex>
#include<condition_variable>
#include<future>
#include<chrono>
using namespace std;
int f(int i)
{
cout << "start" << endl;
cout << "this thread id = " << std::this_thread::get_id() << endl;
std::this_thread::sleep_for(2s);
cout << "end" << endl;
return i;
}
int main(int argc, int * argv[])
{
future<int> fu = std::async(f, 8);
if (fu.wait_for(1s) == std::future_status::timeout) {
cout << "time out" << endl;
}
// 超时继续get
cout << fu.get() << endl;
cout << "main thread id = " << std::this_thread::get_id() << endl;
cout << "main" << endl;
system("pause");
}
The result is as follows:
【7】Set the startup mode of aysnc
#include<iostream>
#include<thread>
#include<mutex>
#include<condition_variable>
#include<future>
#include<chrono>
using namespace std;
int f(int i)
{
cout << "start" << endl;
cout << "this thread id = " << std::this_thread::get_id() << endl;
std::this_thread::sleep_for(2s);
cout << "end" << endl;
return i;
}
int main(int argc, int * argv[])
{
// 设置启动方式为async
future<int> fu = std::async(std::launch::async,f, 8);
if (fu.wait_for(1s) == std::future_status::timeout) {
cout << "time out" << endl;
}
cout << fu.get() << endl;
cout << "main thread id = " << std::this_thread::get_id() << endl;
cout << "main" << endl;
system("pause");
}
The result is as follows: