Search code examples
c++stdasyncstd-future

Strange behaviour when using std::async with std::launch::async


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.


Solution

  • 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.