Different async behavior with Visual Studio 2013 (Windows8.1) and GCC 4.9 (Ubuntu14.10)

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 lasts long after starting.

Func2 should throw an exception.

My observation:

On Windows, the exception is propagated immediately and the main thread (program) will catch it accordingly.

On Linux, the exception persists and the program will not exit until the 1000 second hibernate in Func1 ends.

Does anyone on Linux know how to get a program to immediately catch an exception and exit the program?

+3


source to share


2 answers


future

derived from async

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 does the future destructor return from a std :: async lock? The reason for this behavior is that there is no good portable way to complete the stream.

Then it f2

throws an exception, the destructor is called f1

, which waits for the protector to end (and therefore Func1

) Thus, the block catch

is executed only after completion Func1

.

Like Windows behavior, this is a known VC ++ bug, as discussed here: std :: list <std :: future> destructor is not blocking



So GCC on Linux is right, but VC ++ on Windows is wrong.

For a workaround, see for example a workaround for blocking async?

+3


source


Try to compare in Func1

and the Func2

result:

std::cout << std::this_thread::get_id() << std::endl;

      

async

not guaranteed by the standard to run on a separate thread.



Perhaps you could use std::packaged_task

with std::thread

like in the example:

std::packaged_task< int(int) > package{ Func2 };
std::future<void> f2 = package.get_future();
std::thread t { std::move(package) };

f2.get();       //block here until t finishes

t.join();

      

See my answer regarding std::packaged_task

at fooobar.com/questions/249324 / ...

-1


source







All Articles