[C++ Multithreaded Series] [9] future and async

If we want to get thread processing results asynchronously, we can use future and async.Async returns a future object and waits for the thread to get the processing value of the asynchronous thread on the future object.Asynchronous here, the main thread is actually blocking.

 

[1] Status of future

future has three states:

std::future_status::deferred;  //Indicates that the asynchronous thread has not been started
std::future_status::ready;     //Indicates that the asynchronous thread has finished executing and that the execution result has been written to the future
std::future_status::timeout;   // Indicates that the asynchronous thread processing timed out and did not write the result to the future

[2] Whether async starts threads

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 represents how an asynchronous thread starts, in two ways:

std::launch::async; // Indicates that the async thread is started immediately after the table has used the async function
std::launch::deferred; // Indicates that the thread is delayed starting, and an asynchronous thread is created and started when future.get or future.wait is called

The default way for async is shown in the interface:

std::launch::async | std::launch::deferred  // Indicates whether or not to start a thread is determined by the system load. If the system is overloaded, asynchronous thread calculation may not be started, then the state of the future will not be ready. Normally, this default setting is sufficient, but if asynchronous thread execution is required, the modified startup mode is 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, and the get gets blocked until it gets the data

fu.wait();

The wait statement is as follows:

No return value, wait until the future state is read

fu.wait_for();

The wait_for declaration is as follows:

Wait for a certain amount of time, return the state with a value of future, and return time_out if the wait times out

fu.wait_until(); is to wait until a certain point in time, similar to wait_for.

[4] async uses 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 results are as follows:

You can see that the thread IDs are different here.

[5] First wait, 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 results are as follows:

[6] Wait 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 results are as follows:

If get is returned after a time-out, wait until the future state is ready, then fetch 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;
	}
    // Continue get over time
    cout << fu.get() << endl;



	cout << "main thread id = " << std::this_thread::get_id() << endl;

	cout << "main" << endl;
	system("pause");
}

The results are as follows:

 

[7] Set up aysnc startup mode

#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[])
{
    // Set startup mode to 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 results are as follows:

Posted on Sun, 22 Mar 2020 10:14:13 -0700 by crazycaddy