kri*_*pet 31 c++ multithreading future c++11 stdthread
我对这个std::async
功能有点困惑.
规范说:正在执行的异步操作"好像在新的执行线程中"(C++11§30.6.8/ 11).
现在,这意味着什么?
在我的理解中,代码
std::future<double> fut = std::async(std::launch::async, pow2, num);
Run Code Online (Sandbox Code Playgroud)
应该pow2
在新线程上启动函数并将值传递num
给线程的值,然后在将来某个时候,当函数完成时,将结果放入fut
(只要函数pow2
具有类似的签名double pow2(double);
).但规范说"似乎",这使得整个事情对我来说有点模糊.
问题是:
在这种情况下是否始终启动新线程?希望如此.我的意思是对我来说,参数std::launch::async
是有意义的,我明确说明我确实想要创建一个新线程.
和代码
std::future<double> fut = std::async(std::launch::deferred, pow2, num);
Run Code Online (Sandbox Code Playgroud)
应该通过将函数调用延迟到我写的类似的点来使延迟评估成为可能.在这种情况下,参数,应该意味着我明确说明,我不想要一个新线程,我只是想确保在需要它的返回值时调用该函数.pow2
var = fut.get();
std::launch::deferred
我的假设是否正确?如果没有,请解释.
另外,我知道默认情况下该函数调用如下:
std::future<double> fut = std::async(std::launch::deferred | std::launch::async, pow2, num);
Run Code Online (Sandbox Code Playgroud)
在这种情况下,我被告知是否将启动新线程取决于实现.那又是什么意思呢?
bku*_*ytt 42
的std::async
(的部分<future>
功能模板头)用于启动(可能)异步任务.它返回一个std::future
对象,最终将保存std::async
参数函数的返回值.
当需要该值时,我们在std::future
实例上调用get(); 这将阻塞线程,直到将来准备就绪,然后返回值.std::launch::async
或者std::launch::deferred
可以指定为第一个参数,std::async
以指定任务的运行方式.
std::launch::async
表示函数调用必须在其自己的(新)线程上运行.(将用户@ TC的评论记入帐户).std::launch::deferred
表示函数调用将被推迟到将来调用wait()
或get()
调用.在此之前,未来的所有权可以转移到另一个线程.std::launch::async | std::launch::deferred
表示实施可以选择.这是默认选项(如果您自己未指定).它可以决定同步运行.在这种情况下是否始终启动新线程?
从1开始,我们可以说总是启动一个新线程.
我的假设[在std :: launch :: deferred]是否正确?
从2开始,我们可以说你的假设是正确的.
那是什么意思?[关于正在启动或未启动的新线程,取决于实现]
从3.,std::launch::async | std::launch::deferred
默认选项,它意味着模板函数的实现std::async
将决定它是否将创建新线程.这是因为一些实现可能正在检查过度调度.
警告
以下部分与您的问题无关,但我认为重要的是要记住.
C++标准规定,如果a std::future
保存对与异步函数调用相对应的共享状态的最后一个引用,则std :: future的析构函数必须阻塞,直到异步运行函数的线程结束.因此std::future
返回的实例std::async
将在其析构函数中阻塞.
void operation()
{
auto func = [] { std::this_thread::sleep_for( std::chrono::seconds( 2 ) ); };
std::async( std::launch::async, func );
std::async( std::launch::async, func );
std::future<void> f{ std::async( std::launch::async, func ) };
}
Run Code Online (Sandbox Code Playgroud)
这种误导性代码可能会让您认为std::async
调用是异步的,它们实际上是同步的.std::future
返回的实例std::async
是临时的并且将阻塞,因为它们的析构函数在std::async
返回时被调用,因为它们未分配给变量.
第一次调用std::async
将阻塞2秒,然后再从第二次调用阻止2秒std::async
.我们可能认为最后一次调用std::async
没有阻塞,因为我们将它返回的std::future
实例存储在一个变量中,但由于这是一个在作用域末尾被销毁的局部变量,它实际上会阻塞另外2秒钟.当局部变量f被销毁时,函数范围的结束.
换句话说,调用该operation()
函数将阻止它同步调用的任何线程大约6秒.未来版本的C++标准可能不存在此类要求.
我用来编译这些笔记的信息来源:
C++并发行动:实用多线程,Anthony Williams
Scott Meyers的博文:http://scottmeyers.blogspot.ca/2013/03/stdfutures-from-stdasync-arent-special.html
归档时间: |
|
查看次数: |
16879 次 |
最近记录: |