3

In the below code in VS2015, I'm getting acefbd in the first line, which is correct. but in the 2nd test where I seperate out into individual lines, the output is abcdef.

Is that intended behavior?

#include <future>
#include <iostream>

using namespace std;

void a () {
std::cout << "a";
std::this_thread::sleep_for (std::chrono::seconds (3));
std::cout << "b";
}

void c () {
std::cout << "c";
std::this_thread::sleep_for (std::chrono::seconds (4));
std::cout << "d";
}

void e () {
std::cout << "e";
std::this_thread::sleep_for (std::chrono::seconds (2));
std::cout << "f";
}

int main () 
{
    std::async (std::launch::async, a), std::async (std::launch::async, c),  std::async (std::launch::async, e);

cout << "\n2nd Test" << endl;

std::async (std::launch::async, a);
std::async (std::launch::async, c);
std::async (std::launch::async, e);

}
M.M
  • 138,810
  • 21
  • 208
  • 365
Robin
  • 451
  • 3
  • 14

1 Answers1

8

This has nothing to do with Visual Studio, but what you're doing with the std::future objects that std::async returns.

When a std::future object is destructed, the destructor blocks while waiting for the future to become ready.

What happens with the first line is that you create three future objects, and at the end of the full expression (after you create the last one) the futures go out of scope and are destructed.

In the "2nd Test" you create one future which then has to be destructed before continuing, then you create another future which has to be destructed before continuing, and lastly a third future which of course also has to be destructed.

If you save the futures in the second test in temporary variables, you should get the same behavior:

auto temp_a = std::async (std::launch::async, a);
auto temp_c = std::async (std::launch::async, c);
auto temp_e = std::async (std::launch::async, e);
Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • Do you know in which order the temporaries are destructed? Like is it implementation defined? – Rakete1111 Jul 13 '17 at 07:05
  • @Rakete1111 I assume you mean for the first test using the comma expression? Then no I don't know, not without looking through the specification. – Some programmer dude Jul 13 '17 at 07:07
  • 2
    @Rakete1111 temporaries are destructed in the reverse order of construction within the same full-expression; except for ones which have lifetime extended due to being bound to a reference. (Which these don't). – M.M Jul 13 '17 at 07:08
  • 4
    I think destruction order would not make a difference for your case though, the key point is that all 3 threads are launched before any wait occurs; it doesn't matter when or which order you join the threads after that. BTW it is not guaranteed to see `ace` as the start order, it's likely but perhaps one thread will experience a delay starting up – M.M Jul 13 '17 at 07:11