【问题标题】:Why does std::future::wait_for not behave as expected?为什么 std::future::wait_for 的行为不符合预期?
【发布时间】:2019-08-18 16:58:27
【问题描述】:
#include <iostream>
#include <chrono>
#include <future>

using namespace std::literals;

int main()
{
    std::promise<void> prom;
    auto               fut = prom.get_future();

    std::cout << std::boolalpha << (
         std::future_status::timeout ==
         fut.wait_for(std::chrono::seconds::max())
    );
}

代码应该什么也不输出,因为fut.wait_for 会等待很长时间。但是,它会立即输出true

为什么std::future::wait_for 的行为不符合预期?

【问题讨论】:

  • 这可能是由于相对时间计算中的溢出(system_clock::now() + chrono::seconds::max())。
  • @1201ProgramAlarm 我认为这正是它的本质,g++ 实现就像你的 sn-p 一样转换为绝对时间。
  • 我调试了 g++ 实现,就是这样。尽管 cppreference.com 上的所有“wait_for”都这样描述它们,但我无法从标准中确定是否允许这样做。
  • 我在标准中看不到任何允许此操作无效的内容。提交错误?

标签: c++ multithreading c++11 time future


【解决方案1】:

这是由于相对时间计算溢出导致未定义行为。

我在标准中没有找到专门解决 wait_for 溢出问题的任何内容,因此我们需要依赖溢出的标准处理,这取决于所涉及的底层类型。

std::chrono::secondsstd::duration 的 typedef,使用的类型是至少 35 位的有符号整数类型。添加两个持续时间值涉及添加两个有符号整数。 signed integer addition overflows 时为未定义行为。

因此,当等待很长时间时,行为是不确定的。

【讨论】:

  • "std::chrono::seconds 是 std::ratio 的 typedef。" 不是。而且ratio 的模板参数的类型与此无关。跨度>
  • @T.C.我的措辞基于我链接到的 cppreference 页面中的内容。检查标准,在 [time.syn] 中有一个注释为“// 便利 typedefs”的部分,其中包括 using seconds = duration&lt;signed integer type of at least 35 bits &gt;;。这是一个alias-declaration,它引入了一个typedef-name(参见[dcl.typedef])。 ratio的模板参数的类型是内部存储的类型,是做加法等操作时使用的类型。
  • 我认为你混淆了durationratio
  • @T.C.感谢您指出了这一点。我误读了所说的内容,比前面的文字更关注链接。我(希望)更正了答案。
猜你喜欢
  • 2019-05-09
  • 1970-01-01
  • 1970-01-01
  • 2017-05-17
  • 1970-01-01
  • 2012-12-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多