【发布时间】: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