Windows XP中的std :: async中的std :: async

时间:2018-10-10 08:42:06

标签: c++ visual-c++ windows-xp

此示例在Windows7和ideone.com上打印所有2条消息,但在Windows XP上无法打印第二条消息。我在做什么错?如果是错误,我应该在哪里报告?

使用Visual Studio 2017平台工具集v141_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;
}

在内部功能使用std :: thread而不是std :: async时使用UPS-在两个系统上均能很好地工作

auto f2 = thread([]()->int {
    cout << "in inner async" << endl;
    return 2;
});
f2.join();

UPD2

Visual Studio 2017 cl.exe版本19.14.26428工具集v141_xp

命令行:

/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 

在Windows XP上使用时,UPD3看起来像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();

在Windows7上,这大约需要6秒才能完成,而在Windows XP上则是大约50秒

1 个答案:

答案 0 :(得分:0)

在Windows上,std::async(...)位于线程池的顶部。因此可能存在僵局。在f1内部,您运行新任务并调用f2.get(),该任务将阻塞直到f2完成。但是,如果auto f2 = async(...)选择了运行f1的相同线程,那么您将陷入死锁,并且程序将无法完成。如果是这样,那么情况并非如此。

更新

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

  

C ++标准规定,如果启动policy :: async,该函数将创建一个新线程。但是,Microsoft实施当前不合格。它从Windows ThreadPool获取线程,Windows ThreadPool在某些情况下可能提供回收的线程,而不是新的线程。这意味着launch :: async策略实际上是作为launch :: async | launch :: deferred

实现的

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

  
      
  • 它限制了它使用的后台线程的总数,在此之后,对std :: async的调用将阻塞,直到线程变为空闲为止。在我的机器上,这个数字是768。
  •   

因此,我假设,如果ThreadPool中只有一个线程,则从任务内部对std::async的调用将死锁。考虑到您的 UPD3

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