From VS2013 to VS2017 std::async does not start a

2019-02-26 07:53发布

I updated my Visual Studio from 2013 to 2017. Compiling was fine but it seems like that the std::async call didn't open a new thread. (I cant see a new one in the thread-window while debugging. Also it looks like the thread which calls the the async function does the job...)

That is my function call:

std::async(std::launch::async, myfunction, this); 

I didn't change anything in my code and in VS2013 was everything working fine.

Any Idea? Google can't tell me a lot about this but maybe i have the wrong keywords. So keywords would also help!

Thank you

4条回答
The star\"
2楼-- · 2019-02-26 08:41

Looks like std::async is whaiting for return to end. So, if you symply call it, doesn't work asynchronous.

std::async(std::launch::async, myfunction, this);

The Key is define an answer: myfunction must to return std::future and you need to define and same type to response.

std::future<int> foo = std::async(std::launch::async, myfunction, this);

In case you call std::async inside a constructor, foo must be member of the class.

class MyClass {
    //Your code
    private:
        std::future<int> exitThread;
}

And, when you call std::async must be

exitThread = std::async(std::launch::async, myfunction, this);
查看更多
狗以群分
3楼-- · 2019-02-26 08:50

In VS2013, std::async does not obey the C++ standard.

There was a disagreement, and the developers working on MSVC wanted std::async's std::future to behave like every other std::future.

The standard disagreed.

They released a non-standard compliant std::future in 2013. In 2015 if I remember correctly, they started following the standard.

The standard states that the destructor of the std::future owning the shared state generated by std::async( std::launch::async blocks until the task is complete.

This is because, in practice, dangling threads are bad for programs behaving in a predictable manner.

You are now in charge of owning and persisting the future returned from

auto f = std::async(std::launch::async, myfunction, this); 

and f.wait or f.geting it when you need it to be ready.

This may require changing how your code works; for example, keeping a vector of futures around (if you have more than one), or adding a std::future<?> member to this and storing it (this also ensures that the async call doesn't outlive the object lifetime!).


As a second note, std::async on windows also uses a bounded thread pool; if there are more than a certain number of async tasks active, new tasks may not be launched.

They have plans to fix it (as it goes against the advice in the standard), but at this point I would still recommend using std::thread, and if you need std::async like behavior implementing something similar yourself.

My personal tendency is to create problem-specific thread_pools that own a certain number of std::threads, but let you queue tasks and get futures (with custom extensions that give me very limited continuation capabilities) back from it.

This makes the thread ownership and dependencies more explicit, and avoids dealing with the MSVC non-standard compliant quirks that still exist.

查看更多
Luminary・发光体
4楼-- · 2019-02-26 08:53

You need to hold on to the std::future returned by async otherwise the destructor of the temporary will block until the work is finished.

auto t = std::async(std::launch::async, myfunction, this);
查看更多
劳资没心,怎么记你
5楼-- · 2019-02-26 08:53

Very simple Solution:

std::thread t(myfunction, this);
t.detach();
查看更多
登录 后发表回答