Updated April 15, 2023
Introduction to C++ async
As the name indicates, C++ async is a function template fn, which takes functions or function objects as arguments (basically called callbacks) and runs them asynchronously. It returns the std:: the future object which is used to keep the result of the above function. The result is stored in the shared state. In order to exact the value from it, its member future:: get needs to be called by the programmer. In C++, async functions are used in 2 ways, i.e. with or without specifying the policies in the function arguments. When specifying the launch policy, the first argument is the policy itself which defines the asynchronous behavior of the function.
Syntax and working of C++ async
Below given is the basic syntax of how the async function is used in C++ programs:
There are 2 ways in which the async function can be used:
1. Without specifying the policy
template <class function (Fn), class... Args>
std::future<typename std::result_of<Fn(Args...)>::type>
async (Function && fn, Args&&... args);
In the above syntax, the launch policy is not specified in the function arguments. Launch policy is automatically selected, which is launch:: async | launch:: deferred.
2. Specifying the policy
template <class function(Fn), class... Args>
std::future<typename std::result_of<Fn(Args...)>::type>
async (launch policy, Function && fn, Args&&... args);
In the above syntax, launch policy is mentioned in the function arguments in order to specify before in which policy a function should execute.
where,
Fn: It is the callable object or the function object. The return value of this function ‘fn’ is stored in the shared state, which is accessed by the object ‘future’. In case of exceptions also, the value is set in the shared state, which the future object can also access.
args: It is the arguments or the parameters which are passed in the async function ‘fn’.
One important point to note in the async function is that both the function ‘Fn’ and argument ‘args’ should be move constructible, and the function uses the decay copies of both the Fn and args.
Policy: Policy in C++ async plays an important role in the one which defines the asynchronous behaviour followed using the function async. There are basically 3 ways in which create async using different policies:
S.No | Policy name | Behavior |
1. | launch::async | This launch policy assures the async behavior of the function, which means that the callable function will be executed in a new thread. It follows the easy evaluation policy in which calculation will be evaluated immediately in the work package in the new thread. In case of exception, it is stored in the shared state, which is accessed by std::future. |
2. | launch::deferred | In this launch policy, a callable function is not executed in the new thread; instead, it follows the non-async behavior. It follows the lazy evaluation policy in which the call to the function is deferred (postponed) till the previous thread calls the get on the future object, which makes the shared state again accessible. The function then will no longer be deferred. In this case, the function will run its work package in the same thread. In case of exceptions, it is placed in the shared state of the future; then, it is made ready for the required function. |
3. | launch::async | launch::deferred | This is an automatic launch policy. In this policy, the behavior is not defined. The system can choose either asynchronous or deferred depending on the implementation according to the optimized availability of the system. Programmers have no control over it on anything. |
There are other launching policies available as well depending on the system implementation and can be used with the label ‘launch::’. One can use it by combining multiple values together.
Return Value: The return value of async is the std:: future which is the shared state which is created by the function call of std::async. We can get the values from it using member future::get returned by the function.
Example of C++ async
Let us have a deep understanding of how the async function is used in C++ programs with the help of an example:
// Example of checking the number is even or not using async
#include <iostream> // library used for std::cout
#include <future> // library used for std::async and std::futur
// function for checking the number is even or not
bool check_even (int num) {
std::cout << "Hello I am inside the function!! \n";
//checking the divisibility of number by 2 and returning a bool value
if(num%2==0)
{
return true;
}
return false;
}
int main ()
{
// calling the above function check_even asynchronously and storing the result in future object
std::future<bool> ft = std::async (check_even,10);
std::cout << "Checking whether the number 10 is even or not.\n";
// retrieving the exact value from future object and waiting for check_even to return
bool rs = ft.get();
if (rs) {
std::cout << "Number mentioned by you is even \n";
}
else {
std::cout << "Sorry the number is odd \n";
}
return 0;
}
Output:
Explanation: In the above code, we have checked whether the number is even or not using the async function. #include <future> library is included in order to use future and async functions. The basic function ‘check_even’ is used to check the number passed as an argument returning the boolean value. std:: async function is used asynchronously, and the result is stored in the std::future object. As discussed before, in order to exact value, ‘get’ is used, and the output is printed on the console depending on the boolean value returned.
Exception:
There are many chances in which an exception is thrown using the async function in C++, like when the system is unable to start a new thread on using the std:: async function, ‘system_error’ is thrown. One important point to keep in mind is that when an exception is thrown, all the objects are left in the valid state and caught in a shared state, which the future objects can then access. Depending on the implementation of the system, other specific exceptions are also thrown according to the different situations.
Conclusion
The above description clearly explains the C++ async function and how it is used in the programs. As the async function can be used according to the specific launching policy, it is mandatory to understand all the policies and the code requirements. Being a good programmer, understanding the exception thrown while using this function is also important in order to handle it accordingly.
Recommended Articles
This is a guide to C++ async. Here we discuss the deep understanding of how the async function is used in C++ programs with the help of an example. You may also have a look at the following articles to learn more –