std::未来旋转等待吗
Does std::future spin-wait?
在更详细地解释这个问题之前,我会注意到答案显然取决于实现,所以我主要询问的是libstdc++,但我也有兴趣了解libc++。操作系统是Linux。
在std::future
上调用wait()
或get()
会阻塞,直到通过异步操作(std::promise
、std::packaged_task
或std::asyn
函数)设置结果为止。结果的可用性通过共享状态进行通信,该状态基本上是一个原子变量:future等待promise(或async任务)将共享状态标记为就绪。这个等待和通知是通过futex系统调用在libstdc++中实现的。假设未来的未来只需要等待极短的时间(约为一微秒),那么在等待未来之前,在共享状态上旋转一小段时间,似乎可以获得性能提升。
在当前的实现中,我没有发现任何这种旋转的证据,但是,我确实在atomic_futex.h中的第161行找到了一条注释,我希望在其中找到这种旋转:
// TODO Spin-wait first.
因此,我的问题是:是否真的有计划实施旋转等待,如果有,将如何决定持续时间?此外,这是最终可以通过未来的策略指定的功能类型吗?
我将回答以下问题:std::future::get()
是否执行旋转等待?
所有C++的答案是:它是一个实现细节。一个合格的标准库可能会旋转,也可能不会(同样,std::mutex::lock()
也可以旋转)。是否会有一种机制来指定未来是否旋转以及如何旋转?值得关注的地方有std::experimental::future
(即将推出标准库的完整版本)、boost::future
(稍后可能成为标准的试验场)和hpx::future
(具有高级future
管理功能的性能库)。这些都没有明确规定纺纱的机制,我所知道的会议记录中也没有讨论过,ISO CPP邮件列表中也没有。可以肯定地说,类似get_with_spins
函数的东西不在管道中。
回答libstdc++
(和libc++
):它们也不旋转。除了来自原始补丁的TODO之外,似乎没有任何计划来改变这一点。我在GCC邮件列表中搜索了关于改变这种行为的内容,但没有找到。在一般情况下,进行睡眠前旋转可能会造成伤害(如果get()
都没有值,则浪费了大量CPU周期),因此此处的更改可能会产生负面影响。
总之:实现现在似乎没有旋转,在不久的将来似乎也没有改变行为的计划,但这种情况随时都可能改变。
- 在Linux中哪里可以找到互斥、未来等的源代码
- 为什么我的C#代码在调用回C++COM直到Task时会暂停.等待/线程.加入
- 如何让LLDB在成功时退出,在失败时等待
- C++:Application.cpp中抛出了未解析的外部符号(解决方案在问题的末尾,供未来的读者参考)
- 使用 std::string () const 函数启动线程或未来
- 等待整个 omp 块完成,然后再调用第二个函数
- 提升 ASIO - io_service 不要等待连接到线程
- 如何在C++中实现带有packaged_task的异步等待循环?
- 虚假唤醒是否会解锁所有等待线程,甚至是不相关的线程?
- 如何等待窗口隐藏在Qt中?
- 如何在不等待检索的情况下获取C++中的内存位置?
- 等待被迷住了,没有回来
- QVTKWidget在VTK 8.1中已弃用,并将在未来的版本中删除
- 等待 WaitForMultipleObjects 窗口中的事件数量可变
- C++异步编程,如何不等待未来
- std::未来旋转等待吗
- std::未来等待毁灭
- 等待助推器asio的未来在io_service.stop()之后永远持续下去
- 等待多个未来
- 有没有办法异步等待 Boost Asio 的未来