【问题标题】:Clean-up a timed-out future清理一个超时的未来
【发布时间】:2022-01-24 08:33:46
【问题描述】:

我需要运行一个超时的函数。如果它没有在给定的超时时间内返回,我需要丢弃它并回退到不同的方法。

以下是(非常)简化的示例代码,用于突出问题。 (实际上,这是一个始终在运行的高可用性应用程序。我首先从缓存中读取数据,并且仅当缓存中有陈旧数据时才尝试从数据库中读取数据。但是,如果数据库查询花费了很长时间,我需要继续过时的数据。)

我的问题是,在未来读取超时的情况下,我是否必须单独处理未来的清理(即保留一份副本并不时检查它是否准备就绪)?还是我可以简单地忽略它(即保持代码不变)。

/* DB query can be time-consuming, but the result is fresh */
string readFromDatabase(){
  // ...
  // auto dbValue = db.query("select name from users where id=" + _id);
  // ...
  return dbValue;
}

/* Cache query is instant, but the result could be stale */
string readFromLocalCache(){
  // ...
  // auto cachedVal = _cache[_id];
  // ...
  return cachedVal;
}

int getValue(){
  // Idea:
  //  - Try reading from the database.
  //  - If the db query didn't return within 1 second, fallback to the other method.
  
  using namespace std::chrono_literals;

  auto fut = std::async(std::launch::async, [&](){ return readFromDatabase(); });
  switch (fut.wait_for(1s)){
    case std::future_status::ready: // query returned within allotted time
    {
      auto freshVal = fut.get();
      // update cache
      return freshVal;
    }
    case std::future_status::timeout: // timed out, fallback ------ (*)
    {
      break;
    }
    case std::future_status::deferred: // should not be reached
    {
      break;
    }
  }
  return readFromLocalCache();
  // quetion? what happens to `fut`?
}

【问题讨论】:

  • 由于 lambda 是通过引用捕获的,如果您不想要未定义的行为(取决于其余代码的功能),您可能必须等待未来完成

标签: c++ asynchronous future c++-standard-library


【解决方案1】:

我的问题是,在未来读取超时的情况下,我是否必须单独处理未来的清理(即保留一份副本并不时检查它是否准备好)?还是我可以简单地忽略它(即保持代码不变)。

从我个人的角度来看,这取决于你想要什么。在您当前(最小)的实现下,getValue 函数将被未来的析构函数阻塞(参见cppreference page 和一些SO questions)。

如果您不想要阻塞行为,有一些解决方案,如question 中提出的,例如:

  1. future 移动到某个外部范围
  2. 使用分离的执行器和一些方便的代码/数据结构来处理返回状态
  3. 看看是否可以将future 替换为一些支持超时的 I/O 操作,例如选择/轮询

等等

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-27
    • 2016-08-01
    • 2021-09-04
    • 1970-01-01
    相关资源
    最近更新 更多