[C++ multithreading series] [9] future and async

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:

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325233539&siteId=291194637