C++ 11 feature: C++ Multithreading Tutorial: std::async and std::future

In the previous chapter we studied about promise and future. In this chapter we shall see how to achieve the same using “async” and “future”.

“async” is present in namespace std.

“std::scync” is used to get asynchronous execution of the tasks.

It means, you start a thread, and comeback to the calling function start executing next statements. The thread will be running in parallel.

Now when you need the result from the thread, you will use “.get()” to get the result.

For example: In below code:

1. std::future<int> get_result_future = std::async(func);
2. // Do something...
3. int result = get_result_future.get();

In the first line, we created an async task and assigned the return value to “get_result_future” future variable.

And then we continue to execute further statements and asynchronously the thread will also be executing. Then in line 3, we will get the result from the async task by using the “get()”method.

Simple example for async task:

#include <iostream>       // std::cout
#include <future>         // std::async, std::future
#include <chrono>         // std::chrono::milliseconds
#include <thread>         // std::thread
#include <mutex>          // std::timed_mutex

// for more tutorials visit www.ProDeveloperTutorial.com

using namespace std;

bool is_prime (int x) 
{
  for (int i=2; i<x; ++i) 
  {
    if (x%i==0) 
        return false;
  }
  return true;
}

int main ()
{
    

  std::future<bool> fut = std::async (is_prime, 346573265);

  std::cout << "Checking whether 346573265 is prime.\n";

  bool ret = fut.get(); 

  if (ret) 
    std::cout << "It is prime!\n";
  else 
    std::cout << "It is not prime.\n";

  return 0;
}

Output:

Checking whether 346573265 is prime.
It is not prime.

std:async launch policies:

There are 3 different launch policies:

1. launch::async : It will launch a new thread to call fn.

2. launch::deferred : The call to fn is deferred until the shared state of the returned future is accessed bu “.get()”. It will not create a thread. It is kind of blocking call.

3. launch::async|launch::deferred : The function chooses the policy automatically

Example for launch::async and launch::deferred:

#include <iostream>       // std::cout
#include <future>         // std::async, std::future
#include <chrono>         // std::chrono::milliseconds
#include <thread>         // std::thread
#include <mutex>          // std::timed_mutex
// for more tutorials visit www.ProDeveloperTutorial.com
using namespace std;

void display (char c) 
{
    cout<<"The thread id of display function = "<< this_thread::get_id()<<endl;
  for (int i=0; i<10; ++i)
  {
    std::this_thread::sleep_for (std::chrono::milliseconds(10));
    std::cout << c;
  }
}

int main ()
{
  cout<<"The thread id of main before launch::async  = "<< this_thread::get_id()<<endl;
  std::cout << "with launch::async:\n";
  std::future<void> foo = std::async (std::launch::async,display,'*');
  std::future<void> bar = std::async (std::launch::async,display,'@');
  foo.get();
  bar.get();
  std::cout << "\n\n";

  cout<<"The thread id of main before launch::deferred  = "<< this_thread::get_id()<<endl;
  std::cout << "with launch::deferred:\n";
  foo = std::async (std::launch::deferred,display,'*');
  bar = std::async (std::launch::deferred,display,'@');
  foo.get();
  bar.get();
  std::cout << '\n';

  return 0;
}

Output:

The thread id of main before launch::async = 140698132587968
with launch::async:
The thread id of display function = 140698114365184
The thread id of display function = 140698105972480
@**@@*@*@*@*@*@*@*@*

The thread id of main before launch::deferred = 140698132587968
with launch::deferred:
The thread id of display function = 140698132587968
The thread id of display function = 140698132587968
**********
@@@@@@@@@@

As you can see in the above output, we can say that when we launch with async launch policy, the thread ID of main function and display function are dfferent.

But where as, for the launch policy of differed, the thread ID of main and display function are same.

Hence when you use “async” launch policy new thread will be created, for “deferred” launch policy, new thread will not be created.

Write a Comment

Leave a Comment

Your email address will not be published. Required fields are marked *