std :: async没有使用std :: launch :: async策略启动新线程

Sii*_*las 4 c++ multithreading asynchronous threadpool c++11

如果我用std :: launch :: async策略启动std :: async,它不应该在新线程中启动每个异步任务吗?目前它看起来新的异步任务转移到刚刚完成它的工作的线程.我正在使用VC11作为我的编译器.正如您从输出中看到的那样,当一个新工作者(例如一个工作者多次获得ID为34500的线程)与std :: async一起启动时,它会在之前完成的线程中启动.我对std :: async的理解是错误的还是有一个潜在的工作窃取队列或类似的东西?

Worker (ID=24072) starting.
Worker (ID=34500) starting.
Worker (ID=32292) starting.
Worker (ID=31392) starting.
Worker (ID=17976) starting.
Worker (ID=31580) starting.
Worker (ID=33512) starting.
Worker (ID=33804) starting.
Worker 32292 finished.
Worker (ID=32292) starting.
Worker 17976 finished.
Worker (ID=17976) starting.
Worker 31580 finished.
Worker (ID=31580) starting.
Worker 34500 finished.
Worker (ID=34500) starting.
Worker 34500 finished.
Worker (ID=34500) starting.
Worker 32292 finished.
Worker (ID=32292) starting.
Worker 17976 finished.
Worker (ID=17976) starting.
Worker 34500 finished.
Worker 17976 finished. 
Worker 31580 finished.
Worker 32292 finished.
Worker 33804 finished.
Worker 31392 finished.
Worker 33512 finished.
Worker 24072 finished.
Run Code Online (Sandbox Code Playgroud)

Jam*_*lis 11

如果我std::async使用std::launch::async策略启动它不应该在新线程中启动每个异步任务吗?

该规范要求"执行新的执行线程"(C++11§30.6.8/ 11)执行异步操作.这里的重要词语是: 好像.

当且仅当行为与创建新线程相同时,才能重用已经运行的工作线程.这意味着,例如,thread_local必须在单个线程上执行的异步操作之间重置具有存储类的变量.

线程标识符不必重置,因为线程标识符仅在线程运行时唯一标识线程.如果线程终止,则可以使用第一个线程的标识符启动另一个线程.

是否有潜在的工作窃取队列或类似的东西?

这是特定于实现的.C++ 11线程支持库的Visual C++ 2012实现是在并发运行时(ConcRT)之上构建的,其中包括一个工作窃取任务调度程序.


Bar*_*ski 6

詹姆斯是对的,有一个更正:微软执行launch :: async是不正确的.Redmond的C++并发工作组对此进行了详细讨论.Visual C++ 2012仍处于测试阶段,因此他们可能会将实现更改为符合标准.