有没有人有相当新的std::async
的经验?我们目前正在实现并行文件解析器,它读取文件块并将此块传递给异步函数。
使用Clang(v3.0)这种方式可以很好地使用默认的std::async
策略(取决于实现)。在一台双核机器上,它最多可以激活4个线程,效果非常好。
但是对于GCC(v4.7),文件读取线程不会产生任何新线程,使程序最终完全顺序。
使用std::launch::async
,两个版本几乎都在做同样的事情(应该是这种情况)。
有谁知道GCC的c ++ 11线程功能的当前状态?或者这可能是我们实施中的错误?
简短代码:
while (readNewChunk()) {
Chunk &chunk = fileReader_.getChunk(); //reading the file
ChunkLoader *chunkLoader = new ChunkLoader();
auto ftr = std::async(std::launch::async, &ChunkLoader::createDictionaries, chunkLoader);
dictCreationFutures_.push_back(std::move(ftr));
}
答案 0 :(得分:17)
行为符合规范,即使它不是您想要的。如果您未指定启动策略,则将其视为async|deferred
,这意味着由实现来决定启动策略。如果给出选择,GCC总是选择deferred
。
答案 1 :(得分:4)
EDIT2:我会解释一下。
std :: async承诺'未来';那就是:当你想要它时,它会在那里。它现在可以计算,可以在你要求的时候计算,我们只是承诺它会发生。
就像我下面的海报一样,海湾合作委员会默认延期(这意味着,当它被要求时,它将履行承诺,并且可能不会事先)。这种默认的原因是因为GCC还没有提供适当的C ++ 11线程支持。除了许多其他方面,它没有一个好的内部线程调度程序。这有点像黑客。不,更像是一堆黑客。事实上,如果你在GCC上用C ++ 11编写线程代码,那么当它们实现功能时,它就会正常工作;现在,它大部分都是正常的。我的意思是,你到底得到了结果,对吧?
如果你告诉它启动一个线程,它会,因为它太愚蠢(目前)意识到它可以而且应该自己(不像CLang,它目前有更好的内部线程调度程序)。
编辑:说真的?误导下来改变了!这是我的参考! http://gcc.gnu.org/projects/cxx0x.html。请注意,“并发”下的几乎所有内容(包括“内存模型”)均标注为“否”。 GCC.GNU.org。他们是你知道的海湾合作委员会的权威。
从我的评论中略微编辑:
我真的建议使用Boost。当GCC准备就绪时,它不会成为适当的C ++ 11支持的大跃进。 C ++ 11中的新线程模型需要与GCC或MSVC不同的内存布局,并且它们尚未真正实现。
答案 2 :(得分:1)
所以我明白这是2年后的事情,但我无法帮助但感觉有必要回应@ std' OrgnlDave关于GCC与CLang的评论,注意至少目前,2015年1月,clang版本3.5和GCC版本4.9具有完全相同的行为。当没有提供启动策略时,该行为默认为不同,并且在调用future :: get时执行,并且仅当显式提供异步启动策略时,编译器才会导致在后台执行该函数。
答案 3 :(得分:1)
一个更新的答案:GCC 7.3.0和Clang 6.0都将在默认启动策略的单独线程上执行C:\
工作。两者都将创建与std::async()
个调用一样多的线程(已测试100个调用)。
我不知道GCC的这种行为何时更改。