async has different behavior(implementation) in Windows VS and Linux g++.
I tested it with the following code:
void Func1(){sleep(1000*1000);}
void Func2(){sleep(1000*2);throw runtime_error("An expected exception");}
int main(int argc, char* argv[]){
try{
auto f1 = async(launch::async, Func1);
auto f2 = async(launch::async, Func2);
f2.get();//block here
f1.get();
}catch (exception& e){
printf("exception: %s\n", e.what());
}
return 0;
}
Func1 sleeps for a long time after launch.
Func2 is to throw an exception.
My observation is:
In Windows, the exception is propagated immediately and the main thread(program) will catch it exit accordingly.
In Linux, the exception is held on and the program doesn't exit until the sleep 1000 seconds in Func1 is over.
So does anybody know in Linux, how to make the program catch the exception immediately and exit the program??
The
future
, obtained fromasync
, has a blocking destructor. This "feature" is very controversial and has been discussed many times in the standard committee. See for example this SO question: Why is the destructor of a future returned from `std::async` blocking? The reasoning for such a behaviour is that there is no good portable way to terminate a thread.Then
f2
throws an exception, thef1
's destructor is called, which waits until the tread (and thusFunc1
) finishes. Thus thecatch
block is executed only after theFunc1
finishes.As of Windows behaviour, this is a known VC++ bug, as discussed here: std::list<std::future> destructor does not block
So, GCC on Linux is right, and VC++ on Windows is wrong here.
For a workaround, see for example Workaround for blocking async?