C++ windows xp中的std::async与std::async

C++ windows xp中的std::async与std::async,c++,visual-c++,windows-xp,C++,Visual C++,Windows Xp,此示例在windows7和ideone.com上打印所有2条消息,但在windows xp上无法打印第二条消息。我做错了什么?如果是bug,我应该在哪里报告它 使用visual studio 2017平台工具集v141\U xp为windows xp编译 #include <iostream> #include <future> #include <thread> using namespace std; int main() { auto f1 =

此示例在windows7和ideone.com上打印所有2条消息,但在windows xp上无法打印第二条消息。我做错了什么?如果是bug,我应该在哪里报告它

使用visual studio 2017平台工具集v141\U xp为windows xp编译

#include <iostream>
#include <future>
#include <thread>

using namespace std;
int main()
{
    auto f1 = async(launch::async, []()->int {
        cout << "in outer async" << endl;

         auto f2 = async(launch::async, []()->int {
             cout << "in inner async" << endl;
             return 2;
         });
         f2.get();

        return 1;
    });
    f1.get();

    return 0;
}
UPD3在windows xp上使用时似乎忽略了launch::async

vector<future<void>> v;
for( int i = 0; i < 10; i++ )
    v.push_back(async(launch::async, []() {cout << "thread" << endl; this_thread::sleep_for(5s); }));
for( auto &f : v )
    f.get();
向量v; 对于(int i=0;i<10;i++)
v、 在Windows
std::async(…)
上的push_back(async)(launch::async,[](){cout)位于线程池的顶部。因此可能会出现死锁。在
f1
内部运行新任务并调用
f2.get()
,它会一直阻塞到
f2
完成。但是如果
auto f2=async(…)
选择了运行
f1
的同一线程,则出现死锁,程序不应完成。如果出现死锁,则情况并非如此

更新

请阅读有关Microsoft实现的
std::async
。 它说:

C++标准指出,如果策略是::AcYNC,函数创建一个新线程。但是微软实现目前不符合。它从Windows线程池中获得线程,在某些情况下,它可以提供一个可重用线程而不是一个新线程。这意味着:Assic策略实际上是实现的。d作为启动::异步|启动::延迟

还有一个,它揭示了Microsoft的
std::async
实现的一个特殊功能:

  • 它限制了它使用的后台线程的总数,在此之后,对std::async的调用将被阻止,直到一个线程空闲为止。在我的机器上,这个数字是768
因此,我假设,如果线程池中只有一个线程,那么从任务内部调用
std::async
就会死锁。考虑到UPD3,这可能是您的情况


我真的建议您阅读上面提到的内容,这样您就可以理解为什么Microsoft的
std::async
不同,以及如何正确使用它。

编译器版本?编译器命令?那么会发生什么?是行
cout,但这并不能解释缺少的文本,只是混合的文本。而且,第二个cout只发生在第一个cout之后已完成,因此混合不适用于此情况case@Fl0然后,您应该发布正确的问题描述。“无法打印第二条消息”和“程序刚刚挂起”完全不同。它挂起在哪一行?最好也包括运行线程的调用堆栈。在windows XP上,程序完成了吗?在windows
std::async(…)
中位于线程池的顶部。因此可能会出现死锁。在
f1
中,运行新任务并调用
f2.get()
,它会一直阻塞到
f2
完成。但是如果
auto f2=async(…)
选择了运行
f1
的同一个线程,那么您就出现了死锁,并且您的程序不应该完成。如果出现死锁,则情况并非如此。将内部异步更改为f2=thread(lambda);f2.join();工作是否正常。std::thread的行为是否与std::async不同?当选择运行f1的同一线程时,调用
f2.get()
永远不会导致死锁,而是同步执行。如果您的逻辑在其他异步任务内部创建和获取异步任务的值,将导致随机死锁,使异步完全不可用…我不确定是否遵循此操作。如果两个回调都在同一线程上运行,那么我们之间怎么可能出现死锁是吗?@nicolai如果是这样的话,那真是一个愚蠢的实现。如果
f2
的目的地是同一个线程,
f2.get()
应该只调用回调而不阻塞。当async决定不使用工作线程时,它就是这样工作的。为什么它会阻塞等待它想在自己的线程上执行的事情呢?愚蠢!@nicolai链接文档的哪一部分涵盖了这种情况?
async
with
launch::async
是必需的ave就像一个新线程已经生成一样,当调用
f2.get()
时,执行
f1
的线程准备好执行
f2
。无论实现是使用线程池、生成新线程还是运行主线程中的所有内容,这都应该有效。
/permissive- /Yu"stdafx.h" /GS /GL /analyze- /Wall /Gy /Zc:wchar_t /Zi /Gm- /O2 /sdl /Fd"Release\vc141.pdb" /Zc:inline /fp:precise /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_USING_V110_SDK71_" /D "_UNICODE" /D "UNICODE" /errorReport:prompt /WX- /Zc:forScope /Gd /Oy- /Oi /MD /std:c++17 /FC /Fa"Release\" /EHsc /nologo /Fo"Release\" /Fp"Release\testasync.pch" /diagnostics:classic 
vector<future<void>> v;
for( int i = 0; i < 10; i++ )
    v.push_back(async(launch::async, []() {cout << "thread" << endl; this_thread::sleep_for(5s); }));
for( auto &f : v )
    f.get();