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