Difference in C ++ 11 asynchronous behavior on Mac and Linux

Consider the following C + 11 code:

#include <chrono> #include <future> #include <iostream> #include <thread> using namespace std; int main() { auto start = chrono::steady_clock::now(); auto elapsed = [start](string s) { cout << s << (chrono::steady_clock::now() - start).count() << endl; }; elapsed("A "); auto fut (async([]() { this_thread::sleep_for(chrono::seconds(2)); })); elapsed("B "); this_thread::sleep_for(chrono::seconds(1)); elapsed("C "); fut.wait(); elapsed("D "); return 0; } 

Mac Results

Compiling the specified code on macOS Sierra with the command c++ -std=c++11 -stdlib=libc++ -Wall question.cc -o question and running, I get the output:

 A 27186 B 86970 C 1001961755 D 2001585903 

which is expected. It took a minimum time to get to A and B , waited 1 second, and then got to C and waited the remaining 2 seconds (1 had already expired) to get to D

Mac Compiler:

 $ c++ --version Apple LLVM version 8.0.0 (clang-800.0.38) Target: x86_64-apple-darwin16.0.0 Thread model: posix 

Linux Results

On Linux, I compiled the same code with c++ -std=c++11 -pthread question.cc -o question and ran and got the result:

 A 32423 B 444340 C 1003635793 D 3006121895 

Linux compiler:

 $ c++ --version c++ (Debian 4.9.2-10) 4.9.2 Copyright (C) 2014 Free Software Foundation, Inc. 

I also tried clang++ on Linux, the LLVM C ++ compiler. The same result.

Q

Why is there a complete 2 second gap between C and D on Linux? Was the async task supposed to run in the background? Am I using the wrong compilation options?

+6
source share
1 answer

async accepts as an optional parameter if you want to run it in another thread, or just wait for a .wait call to run the code.

You have chosen "I do not care", omitting it.

If you don't care, indicate if you want it in another thread. If not, you should not be surprised if they wait while you .wait ed start it, or, alternatively, start a new thread and start it there. In your case, one compiler made it lazy, and the other put it in its thread. Both are permitted by standard.

To get the expected behavior, pass std::launch::async as the first argument to std::async .


Now, theoretically, async , without being told how to start it, it is supposed to do something smart. But some compilers sailed and said that โ€œalways doing it is lazy - itโ€™s less work for usโ€ (or always asynchronously), therefore it was always lazy when you let it go.

This is a performance issue. At the moment, you cannot trust async to be smart on all the C ++ 11 compilers you work with. Come back in a decade.

+7
source

Source: https://habr.com/ru/post/1011555/


All Articles