在C ++ And Beyond的this clip开头附近,我听到了std::async
的问题。我有两个问题:
对于初级开发人员,使用std::async
时有哪些规则可以做什么以及应该避免什么?
此视频中出现了哪些问题?它们与this article相关吗?
答案 0 :(得分:22)
有几个问题:
std::async
允许运行时库选择是启动新线程还是在未来调用get()
或wait()
的线程中运行任务。正如赫伯所说,这是你最有可能想要使用的情况。问题是,这使得它对运行时库的QoI开放以获得正确的线程数,并且您不知道该任务是否具有自己的线程,因此使用线程局部变量可能会有问题。正如我所理解的那样,这就是斯科特所关注的。
在明确调用std::launch::deferred
或get()
之前,使用wait()
政策实际上并不会执行任务。这几乎不是你想要的,所以不要这样做。
使用std::launch::async
策略启动新线程。如果你没有跟踪你有多少线程,这可能会导致线程运行太多。
Herb担心std::future
析构函数的行为,它应该等待任务完成,尽管MSVC2012有一个错误,因为它不会等待。
对于初级开发人员,我建议:
std::async
与默认启动政策一起使用。答案 1 :(得分:8)
我无法就使用默认政策的建议提出更多意见。
如果你经历了设计独立计算单元的痛苦,你可能不会期望它们按顺序运行,而有六个CPU会转动它们的拇指,这可能是合法的"发生取决于您选择的编译器。
默认行为的隐含假设是某些复杂的线程池机制将优化任务放置(可能让一些在调用者的CPU上顺序运行),但这是纯粹的幻想,因为没有任何内容指定C ++运行时必须这样做(无论如何都会超出编译器运行时的范围)。
对我而言,这看起来更像是未定义的行为。
一个名为" async"的类。应该启动异步执行单元,除非一些显式和确定性行为参数告诉它。
坦率地说,除了调试目的之外,我无法看到launch::deferred
的用途,除非您打算编写自己的伪调度程序,在这种情况下,您最好使用普通的线程。
所以我的建议是在你使用launch::async
时指定async
,(告诉编译器类似于"嘿,我想要一些异步任务,但真的 async,ok?")如果您只想按顺序执行任务,则根本不使用async
。
如果您的异步任务遇到问题,可以方便地恢复为deferred
政策,以便更轻松地对其进行调试,但这是关于它的。