I am trying to wrap my head around std::async
and std::futures
introduced in C++11.
#include <iostream>
#include <list>
#include <functional>
#include <vector>
#include <algorithm>
#include <thread>
#include <unistd.h>
#include <string>
#include <future>
using namespace std;
int hog_cpu()
{
cout << "hog_cpu" << endl;
volatile unsigned long long i = 0;
for(i = 0; i < 1000000000ULL ; i++);
return 50;
}
int hog_cpu_ex()
{
cout << "hog_cpu_ex" << endl;
volatile unsigned long long i = 0;
for(i = 0; i < 1000000000ULL ; i++);
return 500;
}
int main()
{
cout << "start threads asynchronously" << endl;
std::future<int> f1 = std::async(std::launch::async, hog_cpu);
std::future<int> f2 = std::async(std::launch::async, hog_cpu_ex);
cout << "Get the Results" << endl;
int r1 = f1.get();
int r2 = f2.get();
cout << "result 1: " << r1 << endl;
cout << "result 2: " << r2 << endl;
return 0;
}
The output of the above program that I get is shown below.
start threads asynchronously
Get the Results
hog_cpu_ex
hog_cpu
result 1: 50
result 2: 500
Process finished with exit code 0
My question is since I use std::launch::async
the execution should start immideately using another thread. Where as the output tells me that it prints the line Get the results
and then only the execution starts. (As evident from the logs above). Also hog_cpu_ex
starts before hog_cpu
. Can someone explain why this might be happening.
When you do
std::future<int> f1 = std::async(std::launch::async, hog_cpu);
std::future<int> f2 = std::async(std::launch::async, hog_cpu_ex);
You spin up two more threads of execution. Then the main thread keeps going after it calls each line and won't stop until it hits
int r1 = f1.get();
if f1
hasn't finished yet. Since the main thread keeps going and spinning up a thread takes some time it is pretty reasonable to see Get the Results
print before the threads even start.
As for why do you see
hog_cpu_ex
hog_cpu
instead of the opposite is due to your operating system. It has control over which threads run and when so it is quite possible that it puts f1
to sleep, has space for f2
so it starts it running, and then starts f1
sometime after that.