use*_*710 65 c++ asynchronous future c++11 stdasync
我正在尝试深入探索新C++ 11标准的所有选项,同时使用std :: async并阅读其定义,我注意到两件事,至少在linux下使用gcc 4.8.1:
pthread
,如果你想使用std::async
你需要pthread.在这一点上,我很自然地问为什么选择std :: async甚至是一组简单的仿函数?这是一个根本无法扩展的解决方案,您调用的未来越多,您的程序响应就越少.
我错过了什么吗?你能展示一个被授予以异步,非阻塞方式执行的例子吗?
Jon*_*ely 76
- 它被称为异步,但它有一个真正的"顺序行为",
不,如果您使用该std::launch::async
策略,那么它将在新线程中异步运行.如果您未指定策略,则它可能在新线程中运行.
基本上在你调用与异步函数foo相关联的未来的行中,程序会阻塞,直到执行foo它完成.
它仅在foo未完成时才会阻塞,但如果它是异步运行的(例如,因为您使用该std::launch::async
策略),它可能在您需要之前完成.
- 它取决于与其他人完全相同的外部库,以及更好的非阻塞解决方案,这意味着pthread,如果你想使用std :: async,你需要pthread.
错了,它不必使用Pthreads实现(在Windows上它不是,它使用ConcRT功能.)
在这一点上,我很自然地问为什么选择std :: async甚至是一组简单的仿函数?
因为它保证了线程安全并在线程之间传播异常.你能用一套简单的仿函数做到吗?
这是一个根本无法扩展的解决方案,您调用的未来越多,您的程序响应就越少.
不必要.如果您未指定启动策略,那么智能实现可以决定是启动新线程,还是返回延迟函数,或者在有更多资源可用时返回稍后决定的内容.
现在,对于GCC的实现,如果你不提供启动策略然后使用当前版本,它将永远不会在新线程中运行(有bugzilla报告),但这是该实现的属性,而不是std::async
一般的.您不应该将标准中的规范与特定实现混淆.阅读一个标准库的实现是学习C++ 11的一种不好的方法.
你能展示一个被授予以异步,非阻塞方式执行的例子吗?
这不应该阻止:
auto fut = std::async(std::launch::async, doSomethingThatTakesTenSeconds);
auto result1 = doSomethingThatTakesTwentySeconds();
auto result2 = fut.get();
Run Code Online (Sandbox Code Playgroud)
通过指定启动策略,您可以强制执行异步,如果您在执行时执行其他工作,则结果将在您需要时准备就绪.
jua*_*nza 54
如果您需要异步操作的结果,那么无论您使用哪个库,都必须阻止.这个想法是你可以选择何时阻止,并且希望当你这样做时,你可以阻止一段时间,因为所有的工作都已经完成了.
另请注意,std::async
可以使用策略std::launch::async
或std::launch::deferred
.如果你没有指定它,允许实现选择,并且它可以选择使用延迟评估,这将导致在你尝试从未来获得结果时完成所有工作,从而导致更长的块.因此,如果您想确保工作是异步完成的,请使用std::launch::async
.
Yak*_*ont 14
我认为你的问题是std::future
说它阻止了get
.它仅在结果尚未准备好时才会阻止.
如果您可以安排结果已经准备好,这不是问题.
有很多方法可以知道结果已经准备好了.您可以轮询future
并询问它(相对简单),您可以使用锁或原子数据来传达它已准备好的事实,您可以构建一个框架来将"已完成"的future
项目传递到消费者可以与之交互的队列中,您可以使用某种信号(一次阻止多个事物或轮询).
或者,您可以完成本地可以完成的所有工作,然后阻止远程工作.
举个例子,想象一下并行递归合并排序.它将数组拆分为两个块,然后async
对一个块进行排序,同时对另一个块进行排序.一旦对其一半进行排序,原始线程就无法继续进行,直到第二个任务完成.所以它做了一个.get()
和阻止.一旦两个半部分已经排序,它就可以进行合并(理论上,合并也可以至少部分地并行完成).
此任务的行为类似于在外部与之交互的线性任务 - 完成后,对数组进行排序.
然后我们可以将它包装在一个std::async
任务中,并有一个已future
排序的数组.如果我们想要的话,我们可以添加一个信号程序让我们知道它future
已经完成,但只有当我们有一个等待信号的线程时才有意义.
归档时间: |
|
查看次数: |
55865 次 |
最近记录: |